# HG changeset patch # User Ryan Harkin # Date 1285693205 -3600 # Node ID 5de8145522378cedf6800ec54fb6585260720640 Initial contribution supporting NaviEngine 1 This package_definition.xml will build support for three memory models - Single (sne1_tb) - Multiple (ne1_tb) - Flexible (fne1_tb) diff -r 000000000000 -r 5de814552237 navienginebootldr/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebootldr/bld.inf Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,79 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* base/bsp/hwip_nec_naviengine/ne1_tb_bootloader/bld.inf +* Purpose build the bootloader features of NE1_TB baseport +* +*/ + + + +PRJ_PLATFORMS +ARM4 ARM4SMP ARMV5 ARMV5SMP + +#if !defined(GCCXML) || !defined(NO_GCCXML) + +PRJ_EXTENSIONS + +#if 0 //#ifdef SBSV2 // If using SBSv2 with bootstrap FLM, MEMMODEL MUST begin with a capital letter + +start extension base.bootstrap bootstrap + +option NAME _ne1_tb_bootloader_bootrom +option CPU arm +option MEMMODEL Multiple +option SOURCES ../navienginebsp/ne1_tb/bootstrap/ne1_tb.s ../navienginebsp/ne1_tb/bootstrap/miniboot.s +option EXTRA_SRC_PATH ../navienginebsp/ne1_tb/bootstrap +option INCLUDES ./config.inc + +option EXTRA_EPOC32_INC_PATH $(EPOCROOT)epoc32/include/platform/assp/naviengine +option GENINCLUDES_HEADERS ../../../os/kernelhwsrv/kernel/eka/include/kernel/arm/arm_types.h ../navienginebsp/naviengine_assp/naviengine.h +option E32PATH ../../../os/kernelhwsrv/kernel/eka/../. + +end + +#else // !SBSV2 + +start extension base/bootstrap bootstrap + +#ifdef SYMBIAN_OLD_EXPORT_LOCATION +option INC_PATH $(EPOCROOT)epoc32/include +#else +option INC_PATH $(EPOCROOT)epoc32/include/platform +#endif + +option NAME _ne1_tb_bootloader_bootrom +option CPU arm +option MEMMODEL multiple +option SOURCES ne1_tb.s miniboot.s +option EXTRA_SRC_PATH $(EXTENSION_ROOT)/../navienginebsp/ne1_tb/bootstrap +option INCLUDES $(EXTENSION_ROOT)/config.inc + +option EXTRA_INC_PATH $(EPOCROOT)epoc32/include/platform/assp/naviengine +option GENINCLUDES arm_types.inc naviengine.inc +option E32PATH $(EXTENSION_ROOT)/../../../os/kernelhwsrv/kernel/eka/../. + +end + +#endif // !SBSV2 + +PRJ_MMPFILES + +#ifndef SMP +ubootldr +#endif + +ubootldrldd + +#endif diff -r 000000000000 -r 5de814552237 navienginebootldr/bootloader_variant.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebootldr/bootloader_variant.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,146 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* base\bsp\hwip_nec_naviengine\ne1_tb_bootloader\bootloader_variant.cpp +* +*/ + + + +#define FILE_ID 0x464C5348 +#include "bootldr.h" +#include "ubootldrldd.h" +#include +#include +#include +#include +#include +#include +#include +#include "flash_nor.h" +#include + +TLinAddr ConfigBlockAddress; // Virtual address + +// RAM copy of config block +SBootloaderConfig aConfigBlock; + +// Invoke the flash_nor routines to read a block containing the bootloader +// configuration. +// +// If the block is found to be invalid, create a new block from defaults. +// +GLDEF_C void ReadConfig() + { + TLinAddr FlashAddr; + FlashAddr = (TLinAddr) GetFlashChunk(); // Map flash + + // Config block is last block of the bootloader space before a flashed image + ConfigBlockAddress = FlashAddr + KNORFlashMaxBootloaderSize - KFlashEraseBlockSize; + + // Make sure the region is not blank and that the first word has the + // bootloader cfg uid on it. + if (!BlankCheck(ConfigBlockAddress, KConfigBlockSize) && + (*(volatile TUint32*)ConfigBlockAddress == KUidUBootldrCfgMagic)) + { + // Copy the config block out of flash and into ram + volatile TUint32* j=(volatile TUint32*)ConfigBlockAddress; + TUint32* dest = (TUint32 *)&aConfigBlock; + + for (TUint i=0 ; i> KsRestartCustomRestartReasons)) + { + // In the boot scenario the indicate that the bootloader should + // check for an appropriate file before restarting the USB Mass + // Storage application. + LoadDevice = EBootUSBMS; + } + } + } + + +// Write the config block back into flash +GLDEF_C void WriteConfig() + { + aConfigBlock.iPortNumber=SerialDownloadPort; + aConfigBlock.iBaudRate =SerialBaud; + aConfigBlock.iLoadDevice=LoadDevice; + // XXX Generate a checksum for the config block (excluding the checksum) + + TInt r = Erase(ConfigBlockAddress, KFlashEraseBlockSize); + if (r!=KErrNone) + { + PrintToScreen(_L("Config block failed erase (0x%x)"), r); + RDebug::Printf("Config block failed erase (0x%x)", r); + BOOT_FAULT(); + } + + r=Write(ConfigBlockAddress, KFlashEraseBlockSize, (TUint32 *)&aConfigBlock); + if (r!=KErrNone) + { + PrintToScreen(_L("Config block failed write (0x%x)"), r); + RDebug::Printf("Config block failed write (0x%x)", r); + BOOT_FAULT(); + } + } + + +GLDEF_C void VariantInit() +/** + * Can place variant code here. + */ + { + // Set the bootloader configuration based on values saved in Flash + ReadConfig(); + + // Other variant actions e.g. print out the board information + + return; + } diff -r 000000000000 -r 5de814552237 navienginebootldr/config.inc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebootldr/config.inc Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,177 @@ +; +; Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +; All rights reserved. +; This component and the accompanying materials are made available +; under the terms of "Eclipse Public License v1.0" +; which accompanies this distribution, and is available +; at the URL "http://www.eclipse.org/legal/epl-v10.html". +; +; Initial Contributors: +; Nokia Corporation - initial contribution. +; +; Contributors: +; +; Description: +; + +; +; NE1_TBVariant bootstrap configuration file + +; Include to enable tracing +; GBLL CFG_DebugBootRom + +; Include to initialise debug port in bootstrap without enabling bootstrap +; trace. Useful for __EARLY_DEBUG__ mode. +; GBLL CFG_InitDebugPort + +; Include one of these to select the CPU + GBLL CFG_CPU_ARM11MP + +; Include the following line if this is a bootloader bootstrap +; GBLL CFG_BootLoader + +; Use the alternate entrypoint into the bootstrap code + GBLL CFG_AlternateEntryPoint + +; Defining CFG_CopyRomToAddress will trigger the generic bootstrap code to copy the rom to the nominated location. + INIT_NUMERIC_CONSTANT CFG_CopyRomToAddress, 0x86000000 + +; If you want to supply a custom set of initial vectors (including reset vector) include the following line +; GBLL CFG_CustomVectors +; +; and provide a custom_vectors.inc file + +; Variant Number + INIT_NUMERIC_CONSTANT CFG_HWVD, 0x09080001 + +; Include the following line if default memory mapping should use shared memory. +; Should be defined on multicore (SMP) devices. + GBLL CFG_USE_SHARED_MEMORY + +; On ARM architecture 6 processors, include the following line to override the threshold +; on total physical RAM size at which the multiple memory model switches into large address space mode +; i.e. size>threshold -> 2Gb per process, size<=threshold -> 1Gb per process +; Defaults to 32Mb. +; INIT_NUMERIC_CONSTANT CFG_ARMV6_LARGE_CONFIG_THRESHOLD, + +; For the direct memory model only, include the following line if you wish the exception vectors at the +; start of the bootstrap to be used at all times. This is only relevant if an MMU is present - this option +; is mandatory if not. +; GBLL CFG_UseBootstrapVectors +; +; If the above option is in use (including if no MMU is present) the following symbol should be defined +; to specify the offset from the bootstrap to the kernel image. + INIT_NUMERIC_CONSTANT KernelCodeOffset, 0x4000 + +; Include the following line if you wish to include the ROM autodetection code based on data bus +; capacitance and image repeats. +; GBLL CFG_AutoDetectROM + +; Include the following line to minimise the initial kernel heap size +; On the direct memory model the size of the kernel data area (super page to end of kernel heap) +; is rounded up to the next 1Mb if this is not included, 4K if it is. +; On the moving and multiple models, the size of the initial kernel heap area is rounded up to +; the next 64K if this is not included, 4K if it is. +; GBLL CFG_MinimiseKernelHeap + +; On the moving or multiple memory models, include either or both of the following lines to +; specify the size of the initial kernel heap +; INIT_NUMERIC_CONSTANT CFG_KernelHeapMultiplier, +; INIT_NUMERIC_CONSTANT CFG_KernelHeapBaseSize, +; +; The initial kernel heap size is MAX( + * N / 16, value specified in ROMBUILD ) +; where N is the total physical RAM size in pages. +; defaults to 24K and defaults to 9*16 (ie 9 bytes per page). + +; Uncomment if using ARM1136 processor and ARM1136 Erratum 353494 +; "Rare conditions can cause corruption of the Instruction Cache" +; is fixed on this hardware. +; +; NOTE: The boot table should use this macro to determine whether RONO or RORO permissions +; are used for the exception vectors. If the erratum is not fixed, RORO must be used. +; +; GBLL CFG_CPU_ARM1136_ERRATUM_353494_FIXED + +; Uncomment if using ARM1136 processor and ARM1136 Erratum 364296 +; "Possible Cache Data Corruption with Hit-Under-Miss" +; is fixed on this hardware. +; +; GBLL CFG_CPU_ARM1136_ERRATUM_364296_FIXED + +; Uncomment if using ARM1136 processor and ARM1136 Erratum 399234 +; "Write back data cache entry evicted by write through entry causes data corruption" +; is fixed on this hardware. +; Workaround +; The erratum may be avoided by marking all cacheable memory as one of write through or write back. +; This requires the memory attributes described in the translation tables to be modified by software +; appropriately, or the use of the remapping capability to remap write through regions to non cacheable. +; +; If this macro is enabled, it should be accompanied by: +; "#define __CPU_ARM1136_ERRATUM_399234_FIXED" in variant.mmh +; GBLL CFG_CPU_ARM1136_ERRATUM_399234_FIXED + + +; Uncomment if: +; 1) using ARM1136 processor and ARM1136 Erratum 411920: "Invalidate Entire Instruction Cache +; operation might fail to invalidate some lines if coincident with linefill" +; is fixed on this hardware, or +; 2) using ARM1176 processor and ARM1176 Erratum 415045: "Invalidate Entire Instruction Cache +; operation might fail to invalidate some lines if coincident with linefill +; is fixed on this hardware. +; Workaround: +; 1) Disables the use of of prefetch range cache operations by setting RV bit in Auxiliary Ctrl Reg. +; 2) Replaces Invalidate ICache operation with the sequence defined in the errata document. +; If this macro is enabled, it should be accompanied by: +; "#define __CPU_ARM1136_ERRATUM_411920_FIXED" in variant.mmh +; +; GBLL CFG_CPU_ARM1136_ERRATUM_411920_FIXED + + +; Uncomment if using ARM1136 processor and ARM1136 Erratum 415662: "Invalidate Instruction Cache by +; Index might corrupt cache when used with background prefetch range" is fixed on this hardware. +; Workaround: +; Disables the use of of prefetch range cache operations by setting RV bit in Auxiliary Ctrl Reg. +; +; GBLL CFG_CPU_ARM1136_ERRATUM_415662_FIXED + + +; Uncomment if this variant config needs to support the Shadow Memory Regions +; (SMR) feature in the kernel. Basically allows media based images to be copied +; into memory which is later reserved by the Kernel RAM Allocator. +; One user of the SMR feature is the HCR component when used with media based +; setting repository. Thus variant configs that support the new MHA HCR +; component and expect media based settings must define this macro e.g. NAND +; Core Image ROM, but not BootLoader ROM etc. +; +; GBLL CFG_ENABLE_SMR_SUPPORT + + +; These are deduced from the supplied configuration +; CFG_ARMV6 +; CFG_MMUPresent +; CFG_CachePresent +; CFG_WriteBufferPresent +; CFG_SplitCache +; CFG_SplitTLB +; CFG_AltDCachePresent +; CFG_WriteBackCache +; CFG_CacheWriteAllocate +; CFG_CachePhysicalTag +; CFG_CacheFlushByDataRead +; CFG_CacheFlushByWaySetIndex +; CFG_CacheFlushByLineAlloc +; CFG_CachePolicyInPTE +; CFG_TEX +; CFG_SingleEntryDCacheFlush +; CFG_SingleEntryICacheFlush +; CFG_SingleEntryITLBFlush +; CFG_SingleEntryTLBFlush +; CFG_CacheTypeReg +; CFG_BTBPresent +; CFG_CARPresent +; CFG_PrefetchBuffer +; CFG_FCSE_Present +; CFG_ASID_Present +; CFG_IncludeRAMAllocator + + END diff -r 000000000000 -r 5de814552237 navienginebootldr/inc/bootloader_variantconfig.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebootldr/inc/bootloader_variantconfig.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,98 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* bsp\hwip_nec_naviengine\ne1_tb_bootloader\inc\bootloader_variantconfig.h +* +*/ + + + +#ifndef __CONFIG_H__ +#define __CONFIG_H__ +#include +#include "naviengine.h" +#include "flash_nor.h" +#include + +#define PLATFORM_BUILD 5 + + +// + +#define VARIANT_ZIP _L("NE1_TB.ZIP") +#define VARIANT_BIN _L("NE1_TB.IMG") + +#define __USE_VARIANT_INIT__ + +#define __USE_LOCAL_DRIVES__ +//#define __USE_USBMS__ // NaviEngine cannot support USB Mass Storage - no hardware! +#define __SUPPORT_UNZIP__ // There is very little reason for any variant not to support zipped images? +#define __SUPPORT_FLASH_REPRO__ // NaviEngine has NOR flash support +#define __SUPPORT_FLASH_NAND__ // NaviEngine has onboard NAND flash +#define __SUPPORT_MEMORY_TEST__ + +#define __SUPPORT_COM0_115200__ +#define __SUPPORT_COM0_230400__ +#define __SUPPORT_COM1_115200__ +#define __SUPPORT_COM1_230400__ +#define __SUPPORT_COM2_115200__ +//#define __SUPPORT_COM2_230400__ // NaviEngine cannot run COM2 at 230400 +//#define __SUPPORT_COM3_115200__ // There is no COM3 on the NaviEngine +//#define __SUPPORT_COM3_230400__ // There is no COM3 on the NaviEngine + +const TInt KUartPortNumber=0; +const TInt KYModemGMode=1; + +// pixel bit size. included in first palette entry only. +const TUint KPaletteEntPBS = 0x3000; // 8bpp as the palette is only written in 8bpp + +// Colours used in display.cpp +// Palette entries are RGB565 +const TUint KPaletteEntBlack = 0x0000; +const TUint KPaletteEntMidBlue = 0x0014; +const TUint KPaletteEntMidGreen = 0x0500; +const TUint KPaletteEntMidCyan = 0x0514; +const TUint KPaletteEntMidRed = 0xA000; +const TUint KPaletteEntMidMagenta = 0xA014; +const TUint KPaletteEntMidYellow = 0xA280; +const TUint KPaletteEntDimWhite = 0xA514; +const TUint KPaletteEntGray = 0x528A; +const TUint KPaletteEntBlue = 0x011F; +const TUint KPaletteEntGreen = 0x57EA; +const TUint KPaletteEntCyan = 0x57FF; +const TUint KPaletteEntRed = 0xFA8A; +const TUint KPaletteEntMagenta = 0xFA9F; +const TUint KPaletteEntYellow = 0xFFEA; +const TUint KPaletteEntWhite = 0xFFFF; + + + +const TUint32 KUidUBootldrCfgMagic = 0x10273EC7; + +const TUint KConfigBlockSize = (KFlashEraseBlockSize/4); // size in words + +// Structure of the config block in NOR flash +struct SBootloaderConfig + { + TUint32 iMagic; + TInt32 iCheckSum; + TInt32 iPortNumber; + TBps iBaudRate; + TInt32 iLoadDevice; + // update iReserved padding when adding members to the structure! + TInt32 iReserved[KConfigBlockSize-4]; + }; + + +#endif diff -r 000000000000 -r 5de814552237 navienginebootldr/ubootldr.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebootldr/ubootldr.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include <../navienginebsp/ne1_tb/variant.mmh> + +TARGET VariantTarget(bootldr,exe) +ROMTARGET bootldr.exe +TARGETTYPE EXE +SOURCEPATH ../../../os/kernelhwsrv/brdbootldr/ubootldr +SOURCE main.cpp bootldr.cpp utils.cpp display.cpp menu.cpp +SOURCE unzip.cpp inflate.c loadzip.cpp +SOURCE ymodem.cpp ymodemu.cpp +SOURCE locdrv.cpp +SOURCE flash_nor.cpp +SOURCE usbms.cpp +SOURCE restart.cpp +SOURCE inflate2.cpp + + +SOURCEPATH . +SOURCE bootloader_variant.cpp + +LIBRARY efsrv.lib euser.lib hal.lib econs.lib +OS_LAYER_SYSTEMINCLUDE_SYMBIAN +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + +USERINCLUDE ./inc +USERINCLUDE ../../../os/kernelhwsrv/brdbootldr/ubootldr/inc +USERINCLUDE ../../../os/kernelhwsrv/brdbootldr/ubootldr/ubootldrldd + +capability all diff -r 000000000000 -r 5de814552237 navienginebootldr/ubootldrldd.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebootldr/ubootldrldd.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include "kernel/kern_ext.mmh" +#include <../navienginebsp/ne1_tb/variant.mmh> + + +target VariantTarget(ubootldr,ldd) +targettype ldd +//sourcepath . +SOURCEPATH ../../../os/kernelhwsrv/brdbootldr/ubootldr/ubootldrldd +source ubootldrldd.cpp +epocallowdlldata + +capability all +vendorid 0x70000001 +macro __SECURE_API__ + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/assp.cia --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/assp.cia Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,77 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\assp.cia +* +*/ + + + +#include +#include +#include +#include "navienginecia.h" +#include + + +__NAKED__ void MsTimerTick(TAny* aPtr) + { + // Service 1ms tick interrupt +#ifdef TOGLE_UART_DTR_LINE + asm("ldr r2, 3f"); + asm("add r2,r2,#0x10"); // KHwRoGpio_Port_Value + asm("ldr r2, [r2]"); + asm("mov r3,#%a0" : : "i" ((TInt)(1<<9))); + asm("ands r2,r2,r3"); + asm("ldr r2, 3f"); + asm("add r2,r2,#0xc"); //r2 has KHwWoGpio_Port_Set_Clear_Lo + asm("movne r3,r3,lsl #16"); + asm("str r3,[r2]"); +#endif + asm("ldr r1, 1f "); // Base address of timer 0 + asm("mov r2, #%a0" : : "i" ((TInt)KNETimerGTIInt_TCI)); + asm("str r2, [r1, #%a0]" : : "i" _FOFF(NETimer,iGTInterrupt)); // clear interrupt + asm("ldr r2, 2f "); // set period again needed due to idle tick + asm("str r2, [r1, #%a0]" : : "i" _FOFF(NETimer,iTimerReset)); // supression + asm("b " CSM_ZN7NTimerQ4TickEv); // Tick the millisecond timer + + asm("1: "); + asm(".word %a0" : : "i" ((TInt)KHwTimersBase)); + asm("2: "); + asm(".word %a0" : : "i" ((TInt)66666)); +#ifdef TOGLE_UART_DTR_LINE + asm("3: "); + asm(".word %a0" : : "i" ((TInt)KHwGPIOBase)); +#endif + } + + +__NAKED__ TUint64 DoRead64(TLinAddr /*aAddr*/) + { + asm("ldmia r0, {r0-r1} "); + __JUMP(,lr); + } + + +__NAKED__ void DoWrite64(TLinAddr aAddr, TUint64 aValue) + { +#ifdef __EABI__ + asm("stmia r0, {r2-r3} "); +#else + asm("stmia r0, {r1-r2} "); +#endif + __JUMP(,lr); + } + + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/assp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/assp.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,231 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\assp.cpp +* +*/ + + + +#include +#include + +NaviEngineAssp* NaviEngineAssp::Variant=NULL; +TPhysAddr NaviEngineAssp::VideoRamPhys; + + +DECLARE_STANDARD_ASSP() + +EXPORT_C NaviEngineAssp::NaviEngineAssp() + { + NaviEngineAssp::Variant=this; + iDebugInitialised = EFalse; + + /* Initialize timers 1 and 2 to generate the system timestamp counter */ + NETimer& T1 = NETimer::Timer(1); + NETimer& T2 = NETimer::Timer(2); + + T1.iTimerCtrl = 0; // stop and reset timer 1 + T1.iGTICtrl = 0; // disable timer 1 capture modes + T2.iTimerCtrl = 0; // stop and reset timer 2 + T2.iGTICtrl = 0; // disable timer 2 capture modes + __e32_io_completion_barrier(); +#ifdef __SMP__ + T1.iPrescaler = KNETimerPrescaleBy1; // Timer 1 prescaled by 1 (=66.667MHz) + T2.iPrescaler = KNETimerPrescaleBy1; // Timer 2 prescaled by 1 (=66.667MHz) +#else + T1.iPrescaler = KNETimerPrescaleBy32; // Timer 1 prescaled by 32 (=2.0833MHz) + T2.iPrescaler = KNETimerPrescaleBy32; // Timer 2 prescaled by 32 (=2.0833MHz) +#endif + __e32_io_completion_barrier(); + T1.iGTInterruptEnable = 0; + T2.iGTInterruptEnable = 0; + __e32_io_completion_barrier(); + T1.iGTInterrupt = KNETimerGTIInt_All; + T2.iGTInterrupt = KNETimerGTIInt_All; + __e32_io_completion_barrier(); + T1.iTimerCtrl = KNETimerCtrl_CE; // deassert reset for timer 1, count still stopped + T2.iTimerCtrl = KNETimerCtrl_CE; // deassert reset for timer 2, count still stopped + __e32_io_completion_barrier(); + T1.iTimerReset = 0xfffffeffu; // timer 1 wraps after 2^32-256 counts + T2.iTimerReset = 0xffffffffu; // timer 2 wraps after 2^32 counts + __e32_io_completion_barrier(); + T1.iTimerCtrl = KNETimerCtrl_CE | KNETimerCtrl_CAE; // start timer 1 + __e32_io_completion_barrier(); // make sure timer 1 started before timer 2 + T2.iTimerCtrl = KNETimerCtrl_CE | KNETimerCtrl_CAE; // start timer 2 + __e32_io_completion_barrier(); + + // Each time T1 wraps, (T1-T2) increases by 256 after starting at 0 + // t1=T1; t2=T2; n=(t1-t2)>>8; time = t1 + n * (2^32-256) + + } + +extern void MsTimerTick(TAny* aPtr); + + +EXPORT_C TMachineStartupType NaviEngineAssp::StartupReason() + { + __KTRACE_OPT(KBOOT,Kern::Printf("NaviEngineAssp::StartupReason")); +#ifdef _DEBUG // REMOVE THIS + TUint s = Kern::SuperPage().iHwStartupReason; + __KTRACE_OPT(KBOOT,Kern::Printf("CPU page value %08x", s)); +#endif // REMOVE THIS + // + // TO DO: (mandatory) + // + // Map the startup reason read from the Super Page to one of TMachineStartupType enumerated values + // and return this + // + return EStartupCold; // EXAMPLE ONLY + } + +EXPORT_C void NaviEngineAssp::Init1() + { + __KTRACE_OPT(KBOOT,Kern::Printf("NaviEngineAssp::Init1()")); + // + // TO DO: (optional) + // + NaviEngineInterrupt::Init1(); // initialise the ASSP interrupt controller + + // + // TO DO: (optional) + // + // Initialises any hardware blocks which require early initialisation, e.g. enable and power the LCD, set up + // RTC clocks, disable DMA controllers. etc. + // + TNaviEngine::Init1(); + } + + +EXPORT_C void NaviEngineAssp::Init3() + { + __KTRACE_OPT(KBOOT,Kern::Printf("NaviEngineAssp::Init3()")); + + TNaviEngine::Init3(); + +#ifdef TOGLE_UART_DTR_LINE + AsspRegister::Write32(KHwRwGpio_Port_Control_Enable, 1<<9); +#endif + + + NTimerQ& m=*(NTimerQ*)NTimerQ::TimerAddress(); + iTimerQ=&m; + + // Initialize timer 0 to generate the 1ms periodic system tick + NETimer& NET = NETimer::Timer(0); + NET.iTimerCtrl = 0; // reset counter + NET.iGTICtrl = 0; // disable input capture + __e32_io_completion_barrier(); + NET.iPrescaler = KNETimerPrescaleBy1; // prescaler divides by 1 + __e32_io_completion_barrier(); + NET.iTimerCtrl = KNETimerCtrl_CE; // take timer out of reset + __e32_io_completion_barrier(); + NET.iTimerReset = 66666; // clocks before timer reset (66.666MHz clock frequency) + __e32_io_completion_barrier(); + NET.iGTInterrupt = KNETimerGTIInt_All; // clear any pending interrupts + __e32_io_completion_barrier(); + NET.iGTInterruptEnable = KNETimerGTIIntE_TCE; // enable counter reset interrupt + __e32_io_completion_barrier(); + NET.iTimerCtrl = KNETimerCtrl_CE | KNETimerCtrl_CAE; // start counter + __e32_io_completion_barrier(); + + // + // TO DO: (mandatory) + // + // If Hardware Timer used for System Ticks cannot give exactly the period required store the initial rounding value + // here which is updated every time a match occurrs. Note this leads to "wobbly" timers whose exact period change + // but averages exactly the required value + // e.g. + // m.iRounding=-5; + // + + TInt r=Interrupt::Bind(KIntIdOstMatchMsTimer,MsTimerTick,&m); // bind the System Tick interrupt + if (r<0) + Kern::Fault("BindMsTick",r); + + // + // TO DO: (mandatory) + // + // Clear any pending OST interrupts and enable any OST match registers. + // If possible may reset the OST here (to start counting from a full period). Set the harwdare to produce an + // interrupt on full count + // + + r=Interrupt::Enable(r); // enable the System Tick interrupt + if (r!=KErrNone) + Kern::Fault("EnbMsTick",r); + + // Allocate physical RAM for video buffer. + TInt vSize=VideoRamSize(); + r=Epoc::AllocPhysicalRam(2*vSize,NaviEngineAssp::VideoRamPhys); //Alloc memory for both secure and non-secure display. + if (r!=KErrNone) + Kern::Fault("AllocVRam",r); + } + +EXPORT_C TInt NaviEngineAssp::MsTickPeriod() + { + // Return the OST tick period (System Tick) + return 1000; + } + +EXPORT_C TInt NaviEngineAssp::SystemTimeInSecondsFrom2000(TInt& aTime) + { + aTime=(TInt)TNaviEngine::RtcData(); + __KTRACE_OPT(KHARDWARE,Kern::Printf("RTC READ: %d",aTime)); + return KErrNone; + } + +EXPORT_C TInt NaviEngineAssp::SetSystemTimeInSecondsFrom2000(TInt aTime) + { + // + // TO DO: (optional) + // + // Check if the RTC is running and is stable + // + __KTRACE_OPT(KHARDWARE,Kern::Printf("Set RTC: %d",aTime)); + TNaviEngine::SetRtcData(aTime); + __KTRACE_OPT(KHARDWARE,Kern::Printf("RTC: %d",TNaviEngine::RtcData())); + return KErrNone; + } + +EXPORT_C TUint32 NaviEngineAssp::NanoWaitCalibration() + { + // + // TO DO: (mandatory) + // + // Return the minimum time in nano-seconds that it takes to execute the following code: + // nanowait_loop: + // subs r0, r0, r1 + // bhi nanowait_loop + // + // If accurate timings are required by the Base Port, then it should provide it's own implementation + // of NanoWait which uses a hardware counter. (See Kern::SetNanoWaitHandler) + // + + return 0; // EXAMPLE ONLY + } + +EXPORT_C void NaviEngineAssp::DebugOutput(TUint aLetter) +// +// Output a character to the debug port +// + { + if (!iDebugInitialised) + { + TNaviEngine::InitDebugOutput(); + iDebugInitialised = ETrue; + } + TNaviEngine::DoDebugOutput(aLetter); + } + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/bmarm/ei2su.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/bmarm/ei2su.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,34 @@ +EXPORTS + WriteTransmitRegister__3I2siQ23I2s14TI2sFramePhasei @ 1 NONAME R3UNUSED ; I2s::WriteTransmitRegister(int, I2s::TI2sFramePhase, int) + DisableDMA__3I2sii @ 2 NONAME R3UNUSED ; I2s::DisableDMA(int, int) + DisableFIFOInterrupts__3I2siQ23I2s14TI2sFramePhasei @ 3 NONAME R3UNUSED ; I2s::DisableFIFOInterrupts(int, I2s::TI2sFramePhase, int) + DisableFIFO__3I2siQ23I2s14TI2sFramePhasei @ 4 NONAME R3UNUSED ; I2s::DisableFIFO(int, I2s::TI2sFramePhase, int) + DisableRegisterInterrupts__3I2siQ23I2s14TI2sFramePhasei @ 5 NONAME R3UNUSED ; I2s::DisableRegisterInterrupts(int, I2s::TI2sFramePhase, int) + EnableDMA__3I2sii @ 6 NONAME R3UNUSED ; I2s::EnableDMA(int, int) + EnableFIFOInterrupts__3I2siQ23I2s14TI2sFramePhasei @ 7 NONAME R3UNUSED ; I2s::EnableFIFOInterrupts(int, I2s::TI2sFramePhase, int) + EnableFIFO__3I2siQ23I2s14TI2sFramePhasei @ 8 NONAME R3UNUSED ; I2s::EnableFIFO(int, I2s::TI2sFramePhase, int) + EnableRegisterInterrupts__3I2siQ23I2s14TI2sFramePhasei @ 9 NONAME R3UNUSED ; I2s::EnableRegisterInterrupts(int, I2s::TI2sFramePhase, int) + GetDelayCycles__3I2siQ23I2s14TI2sFramePhaseRi @ 10 NONAME R3UNUSED ; I2s::GetDelayCycles(int, I2s::TI2sFramePhase, int &) + GetFrameFormat__3I2siRiT2 @ 11 NONAME R3UNUSED ; I2s::GetFrameFormat(int, int &, int &) + GetInterfaceConfiguration__3I2siR5TDes8 @ 12 NONAME R3UNUSED ; I2s::GetInterfaceConfiguration(int, TDes8 &) + GetSampleLength__3I2siQ23I2s14TI2sFramePhaseRi @ 13 NONAME R3UNUSED ; I2s::GetSampleLength(int, I2s::TI2sFramePhase, int &) + GetSamplingRate__3I2siRi @ 14 NONAME R3UNUSED ; I2s::GetSamplingRate(int, int &) + IsDMAEnabled__3I2siRi @ 15 NONAME R3UNUSED ; I2s::IsDMAEnabled(int, int &) + IsFIFOEnabled__3I2siQ23I2s14TI2sFramePhaseRi @ 16 NONAME R3UNUSED ; I2s::IsFIFOEnabled(int, I2s::TI2sFramePhase, int &) + IsFIFOInterruptEnabled__3I2siQ23I2s14TI2sFramePhaseRi @ 17 NONAME R3UNUSED ; I2s::IsFIFOInterruptEnabled(int, I2s::TI2sFramePhase, int &) + IsRegisterInterruptEnabled__3I2siQ23I2s14TI2sFramePhaseRi @ 18 NONAME R3UNUSED ; I2s::IsRegisterInterruptEnabled(int, I2s::TI2sFramePhase, int &) + IsStarted__3I2siQ23I2s13TI2sDirectionRi @ 19 NONAME R3UNUSED ; I2s::IsStarted(int, I2s::TI2sDirection, int &) + ReadFIFOLevel__3I2siQ23I2s14TI2sFramePhaseQ23I2s13TI2sDirectionRi @ 20 NONAME ; I2s::ReadFIFOLevel(int, I2s::TI2sFramePhase, I2s::TI2sDirection, int &) + ReadFIFOModeStatus__3I2siQ23I2s14TI2sFramePhaseRi @ 21 NONAME R3UNUSED ; I2s::ReadFIFOModeStatus(int, I2s::TI2sFramePhase, int &) + ReadReceiveRegister__3I2siQ23I2s14TI2sFramePhaseRi @ 22 NONAME R3UNUSED ; I2s::ReadReceiveRegister(int, I2s::TI2sFramePhase, int &) + ReadRegisterModeStatus__3I2siQ23I2s14TI2sFramePhaseRi @ 23 NONAME R3UNUSED ; I2s::ReadRegisterModeStatus(int, I2s::TI2sFramePhase, int &) + ReadTransmitRegister__3I2siQ23I2s14TI2sFramePhaseRi @ 24 NONAME R3UNUSED ; I2s::ReadTransmitRegister(int, I2s::TI2sFramePhase, int &) + SetDelayCycles__3I2siQ23I2s14TI2sFramePhasei @ 25 NONAME R3UNUSED ; I2s::SetDelayCycles(int, I2s::TI2sFramePhase, int) + SetFIFOThreshold__3I2siQ23I2s14TI2sFramePhaseQ23I2s13TI2sDirectioni @ 26 NONAME ; I2s::SetFIFOThreshold(int, I2s::TI2sFramePhase, I2s::TI2sDirection, int) + SetFrameLengthAndFormat__3I2siQ23I2s15TI2sFrameLengthi @ 27 NONAME R3UNUSED ; I2s::SetFrameLengthAndFormat(int, I2s::TI2sFrameLength, int) + SetSampleLength__3I2siQ23I2s14TI2sFramePhaseQ23I2s16TI2sSampleLength @ 28 NONAME R3UNUSED ; I2s::SetSampleLength(int, I2s::TI2sFramePhase, I2s::TI2sSampleLength) + SetSamplingRate__3I2siQ23I2s16TI2sSamplingRate @ 29 NONAME R3UNUSED ; I2s::SetSamplingRate(int, I2s::TI2sSamplingRate) + Start__3I2sii @ 30 NONAME R3UNUSED ; I2s::Start(int, int) + Stop__3I2sii @ 31 NONAME R3UNUSED ; I2s::Stop(int, int) + ConfigureInterface__3I2siP5TDes8 @ 32 NONAME R3UNUSED ; I2s::ConfigureInterface(int, TDes8 *) + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/bmarm/kanaviengine.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/bmarm/kanaviengine.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,32 @@ +EXPORTS + __14NaviEngineAssp @ 1 NONAME R3UNUSED ; NaviEngineAssp::NaviEngineAssp(void) + Bind__9InterruptiPFPv_vPv @ 2 NONAME R3UNUSED ; Interrupt::Bind(int, void (*)(void *), void *) + BootWaitMilliSeconds__11TNaviEnginei @ 3 NONAME R3UNUSED ; TNaviEngine::BootWaitMilliSeconds(int) + Clear__9Interrupti @ 4 NONAME R3UNUSED ; Interrupt::Clear(int) + CpuVersionId__11TNaviEngine @ 5 NONAME R3UNUSED ; TNaviEngine::CpuVersionId(void) + DebugOutput__14NaviEngineAsspUi @ 6 NONAME R3UNUSED ; NaviEngineAssp::DebugOutput(unsigned int) + DebugPortAddr__11TNaviEngine @ 7 NONAME R3UNUSED ; TNaviEngine::DebugPortAddr(void) + Disable__9Interrupti @ 8 NONAME R3UNUSED ; Interrupt::Disable(int) + Enable__9Interrupti @ 9 NONAME R3UNUSED ; Interrupt::Enable(int) + Init1__14NaviEngineAssp @ 10 NONAME R3UNUSED ; NaviEngineAssp::Init1(void) + Init3__14NaviEngineAssp @ 11 NONAME R3UNUSED ; NaviEngineAssp::Init3(void) + Modify16__12AsspRegisterUlUsUs @ 12 NONAME R3UNUSED ; AsspRegister::Modify16(unsigned long, unsigned short, unsigned short) + Modify32__12AsspRegisterUlUlUl @ 13 NONAME R3UNUSED ; AsspRegister::Modify32(unsigned long, unsigned long, unsigned long) + Modify64__12AsspRegisterUlUxUx @ 14 NONAME ; AsspRegister::Modify64(unsigned long, unsigned long long, unsigned long long) + Modify8__12AsspRegisterUlUcUc @ 15 NONAME R3UNUSED ; AsspRegister::Modify8(unsigned long, unsigned char, unsigned char) + MsTickPeriod__14NaviEngineAssp @ 16 NONAME R3UNUSED ; NaviEngineAssp::MsTickPeriod(void) + NanoWaitCalibration__14NaviEngineAssp @ 17 NONAME R3UNUSED ; NaviEngineAssp::NanoWaitCalibration(void) + ProcessorPeriodInPs__11TNaviEngine @ 18 NONAME R3UNUSED ; TNaviEngine::ProcessorPeriodInPs(void) + Read64__12AsspRegisterUl @ 19 NONAME R3UNUSED ; AsspRegister::Read64(unsigned long) + RtcData__11TNaviEngine @ 20 NONAME R3UNUSED ; TNaviEngine::RtcData(void) + SetPriority__9Interruptii @ 21 NONAME R3UNUSED ; Interrupt::SetPriority(int, int) + SetRtcData__11TNaviEngineUi @ 22 NONAME R3UNUSED ; TNaviEngine::SetRtcData(unsigned int) + SetSystemTimeInSecondsFrom2000__14NaviEngineAsspi @ 23 NONAME R3UNUSED ; NaviEngineAssp::SetSystemTimeInSecondsFrom2000(int) + StartupReason__11TNaviEngine @ 24 NONAME R3UNUSED ; TNaviEngine::StartupReason(void) + StartupReason__14NaviEngineAssp @ 25 NONAME R3UNUSED ; NaviEngineAssp::StartupReason(void) + SystemTimeInSecondsFrom2000__14NaviEngineAsspRi @ 26 NONAME R3UNUSED ; NaviEngineAssp::SystemTimeInSecondsFrom2000(int &) + Unbind__9Interrupti @ 27 NONAME R3UNUSED ; Interrupt::Unbind(int) + VideoRamPhys__11TNaviEngine @ 28 NONAME R3UNUSED ; TNaviEngine::VideoRamPhys(void) + Write64__12AsspRegisterUlUx @ 29 NONAME ; AsspRegister::Write64(unsigned long, unsigned long long) + AsicInitialise__Fv @ 30 NONAME R3UNUSED ; AsicInitialise(void) + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/bmarm/pciu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/bmarm/pciu.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,25 @@ +EXPORTS + Write8__12TConfigSpaceUlUc @ 1 NONAME R3UNUSED ; TConfigSpace::Write8(unsigned long, unsigned char) + CreateChunk__3PciiRP12DPlatChunkHwiUiRUl @ 2 NONAME ; Pci::CreateChunk(int, DPlatChunkHw *&, int, unsigned int, unsigned long &) + CreateChunk__3PciiRP6DChunkR16TChunkCreateInfoUiUiRUl @ 3 NONAME ; Pci::CreateChunk(int, DChunk *&, TChunkCreateInfo &, unsigned int, unsigned int, unsigned long &) + CreateMapping__3PciiUliRUl @ 4 NONAME ; Pci::CreateMapping(int, unsigned long, int, unsigned long &) + GetConfigSpace__12TPciFunction @ 5 NONAME R3UNUSED ; TPciFunction::GetConfigSpace(void) + GetConfigSpace__3Pcii @ 6 NONAME R3UNUSED ; Pci::GetConfigSpace(int) + GetMemorySpace__12TPciFunctioni @ 7 NONAME R3UNUSED ; TPciFunction::GetMemorySpace(int) + GetMemorySpace__3Pciii @ 8 NONAME R3UNUSED ; Pci::GetMemorySpace(int, int) + GetPciAddress__3PciiRUl @ 9 NONAME R3UNUSED ; Pci::GetPciAddress(int, unsigned long &) + GetPhysicalAddress__3PciiRUl @ 10 NONAME R3UNUSED ; Pci::GetPhysicalAddress(int, unsigned long &) + Modify16__12TConfigSpaceUlUsUs @ 11 NONAME ; TConfigSpace::Modify16(unsigned long, unsigned short, unsigned short) + Modify32__12TConfigSpaceUlUlUl @ 12 NONAME ; TConfigSpace::Modify32(unsigned long, unsigned long, unsigned long) + Modify8__12TConfigSpaceUlUcUc @ 13 NONAME ; TConfigSpace::Modify8(unsigned long, unsigned char, unsigned char) + Probe__3PciRt6RArray1ZiUsUs @ 14 NONAME R3UNUSED ; Pci::Probe(RArray &, unsigned short, unsigned short) + Read16__12TConfigSpaceUl @ 15 NONAME R3UNUSED ; TConfigSpace::Read16(unsigned long) + Read32__12TConfigSpaceUl @ 16 NONAME R3UNUSED ; TConfigSpace::Read32(unsigned long) + Read8__12TConfigSpaceUl @ 17 NONAME R3UNUSED ; TConfigSpace::Read8(unsigned long) + RemoveChunk__3PciiP12DPlatChunkHw @ 18 NONAME R3UNUSED ; Pci::RemoveChunk(int, DPlatChunkHw *) + RemoveMapping__3PciiUl @ 19 NONAME R3UNUSED ; Pci::RemoveMapping(int, unsigned long) + Size__10TAddrSpace @ 20 NONAME R3UNUSED ; TAddrSpace::Size(void) + Write16__12TConfigSpaceUlUs @ 21 NONAME R3UNUSED ; TConfigSpace::Write16(unsigned long, unsigned short) + Write32__12TConfigSpaceUlUl @ 22 NONAME R3UNUSED ; TConfigSpace::Write32(unsigned long, unsigned long) + ChunkCleanupCallback__3PciP13TChunkCleanup @ 23 NONAME R3UNUSED ; Pci::ChunkCleanupCallback(TChunkCleanup *) + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/csi/csi_master.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/csi/csi_master.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,1000 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include +#include +#include +#include +#include "csi_psl.h" +#include "csi_master.h" + +#include "hcrconfig.h" +#include "hcrconfig_csi.h" + +// This method ensures, that all Timers have been canceled.. +// interrupts disabled prior to completing the request. +// This method is used to complete request and notify PIL in various situations. +void DCsiChannelMaster::ExitComplete(TInt aErr, TBool aComplete /*= ETrue*/) + { + __KTRACE_OPT(KIIC, Kern::Printf("ExitComplete, r %d, complete %d", aErr, aComplete)); + + // make sure we've disabled ints and canceled dfcs/timers.. + // Disable interrupts for CSI + Interrupt::Disable(iInterruptId); + + // cancel timers and DFCs.. + CancelTimeOut(); + iHwGuardTimer.Cancel(); + iTransferEndDfc.Cancel(); + + // change state to EIdle.. + iState = EIdle; + + // complete the request..calling the PIL method + if(aComplete) + { + CompleteRequest(aErr); + } + } + +// this is call-back for iHwGuard timer. It is called in the ISR context +// if the iHwGuardTimer expires. +// It will change the iTransactionStatus to KErrTimedOut to allow exiting from the while-loop.. +void DCsiChannelMaster::TimeoutCallback(TAny* aPtr) + { + __KTRACE_OPT(KIIC, Kern::Printf("DCsiChannelMaster::TimeoutCallback")); + DCsiChannelMaster *a = (DCsiChannelMaster*) aPtr; + a->iTransactionStatus = KErrTimedOut; + } + +// This method is called by the PIL in the case of timeout for the transaction expiration. +// The PIL will call CompleteRequest() after this function returns, so we need only to clean-up +// and de-assert the SS line. +TInt DCsiChannelMaster::HandleSlaveTimeout() + { + __KTRACE_OPT(KIIC, Kern::Printf("HandleSlaveTimeout")); + + // make sure, that CSIE bit is cleared (disable the interface) + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, KHtCSIModeEnable, 0); + + // stop the driver's operation.. + ExitComplete(KErrTimedOut, EFalse); + + // bring the CS signal pin back to inactive state.. + GPIO::SetOutputState(iSSPin, iSSPinActiveStateOff); + + return KErrTimedOut; + } + +//DFC for TransferComplete +void DCsiChannelMaster::TransferEndDfc(TAny* aPtr) + { + __KTRACE_OPT(KIIC, Kern::Printf("DCsiChannelMaster::TransferEndDfc")); + DCsiChannelMaster *a = (DCsiChannelMaster*) aPtr; + + // we are still receiving the data, so must wait until the end of the transmission + // start the guard timer, which - in case of the following while got stucked - will + // unblock this dfc by changing iTransactionStatus + a->iTransactionStatus = KErrNone; + + a->iHwGuardTimer.OneShot(NKern::TimerTicks(a->iHwTimeoutValue)); + + // active wait until the transfer has finished + while((AsspRegister::Read32(a->iChannelBase + KHoCSIModeControl) & KHtCSIModeTransferState) && + (a->iTransactionStatus == KErrNone)); + + // bring the CS signal pin back to inactive state, but only if this is not an extended transaction, + // in which case we want to leave the bus alone so that the multiple transactions making up the + // extended transaction become one big transaction as far as the bus is concerned + if (!(a->iCurrTransaction->Flags() & KTransactionWithMultiTransc)) + { + GPIO::SetOutputState(a->iSSPin, a->iSSPinActiveStateOff); + } + + // clear CSIE bit.. + AsspRegister::Modify32(a->iChannelBase + KHoCSIModeControl, KHtCSIModeEnable, 0); + + // check if the the guard timer or transaction timer hasn't expired.. + if(a->iTransactionStatus != KErrNone) + { + __KTRACE_OPT(KIIC, Kern::Printf("CsiChannelMaster::TransferEndDfc(): Transaction timed-out")); + a->ExitComplete(a->iTransactionStatus); // report the error situation.. + return; + } + else + { + a->iHwGuardTimer.Cancel(); + } + + // drain the Rx FIFO buffer (there might be one item left) + if(a->iOperation.iOp.iIsReceiving) + { + if(AsspRegister::Read32(a->iChannelBase + KHoCSIIFifoL) && + (a->iRxDataEnd - a->iRxData >= a->iWordSize)) + { + TUint16 val = AsspRegister::Read32(a->iChannelBase + KHoCSIIFifo); + + // we're big-endian.. (AB).. + // so in 16bit mode we need to read MSB first.. + if(a->iWordSize > 1) + { + *a->iRxData = val >> 8; // MSB shifted down.. + *(a->iRxData + 1) = val & 0xff; // LSB.. + } + else + { + *a->iRxData = val; + } + + // increment the pointer.. + a->iRxData += a->iWordSize; + } + } + // else - we don't care about the read data, it will be flushed before the next transfer.. + + // check, if there are more transfers in this transaction + if(a->iState == EBusy) + { + TInt err = a->ProcessNextTransfers(); + + // if for any reason coudln't start next transfer-complete the transaction with err.. + if(err != KErrNone) + { + a->ExitComplete(err); + } + } + } + +// ISR Handler +void DCsiChannelMaster::CsiIsr(TAny* aPtr) + { + DCsiChannelMaster *a = (DCsiChannelMaster*) aPtr; + + // read the interrupt flags - to see, what was causing the interrupt.. + TUint32 status = AsspRegister::Read32(a->iChannelBase + KHoCSIIntStatus); + + // process TEND end interrupts + // this ISR happens every time ONE unit has been transfered.. + if(status & KHtCSIIntStatusTEnd) + { + // clear TxEnd interrupt.. + AsspRegister::Write32(a->iChannelBase + KHoCSIIntStatus, KHtCSIIntStatusTEnd); + + if(a->iTxData == a->iTxDataEnd) + { + // if the Tx FIFO is empty (this was the last item transferred) + // confirm that the transfer was completed successfully: + // - set the transfer status as KErrNone + // - disable interrupts.. + // - queue a DFC, which will finish the Tx-asserting/de-asserting CS line + // and start another transfer in the transaction or complete transaction + if(!AsspRegister::Read32(a->iChannelBase + KHoCSIOFifoL)) + { + Interrupt::Disable(a->iInterruptId); + a->iTransferEndDfc.Add(); + } + } + else + { + // if tere's more data to be sent - copy next item to the FIFO window register. + // if we are in 'receive-only' mode - (e.g. simple read request) we're only + // sending '0' (or other value defined as KValueSentOnRead) - to generate a clock for the slave. + if(a->iOperation.iOp.iIsTransmitting) + { + // copy data to the FIFO.. + TUint16 val; + + // in 16bit mode we need to write two bytes as once MSB first.. + if(a->iWordSize > 1) + { + val = (*a->iTxData) << 8; // MSB shifted up.. + val |= *(a->iTxData + 1) & 0xff; // LSB.. + } + else + { + val = *a->iTxData; + } + + // write this value to the register.. + AsspRegister::Write32(a->iChannelBase + KHoCSIOFifo, val); + + // increment the pointer.. + a->iTxData += a->iWordSize; + } + } + } //end of TXEnd processing + + // process receive threshold interrupt + if(status & KHtCSIIntStatusRxTrgIE) + { + // read data from the FIFO .. + if(a->iOperation.iOp.iIsReceiving) + { + while(AsspRegister::Read32(a->iChannelBase + KHoCSIIFifoL)) + { + // if there's still some place in the buffer - put it into buffer.. + if((a->iRxDataEnd - a->iRxData) >= a->iWordSize) + { + // copy data from the FIFO if tere's more space in the buffer + TUint16 val = AsspRegister::Read32(a->iChannelBase + KHoCSIIFifo); + + // we're big-endian.. (AB).. + // so in 16bit mode we need to read MSB first.. + if(a->iWordSize > 1) + { + *a->iRxData = val >> 8; // MSB shifted down.. + *(a->iRxData + 1) = val & 0xff; // LSB.. + } + else + { + *a->iRxData = val; + } + } + else + { + // overrun, i.e Slave has sent more data than expected by the client + // (e.g. too small buffer size for the transmission) + a->iTransactionStatus = KErrOverflow; + break; + } + + // increment the pointer.. + a->iRxData += a->iWordSize; + } + } + else + { + // or drop the data, writing 0 to the FIFOL register + AsspRegister::Write32(a->iChannelBase + KHoCSIIFifoL, 0); + } + + // if we are in the 'half-duplex' 'receive only' mode, + // once the receive buffer is full we are to finish the transmission.. + if((a->iOperation.iValue == TCsiOperationType::EReceiveOnly) && + (a->iRxDataEnd == a->iRxData)) + { + Interrupt::Disable(a->iInterruptId); + a->iTransferEndDfc.Add(); + } + + // Clear the RxThreshold interrupt + AsspRegister::Write32(a->iChannelBase + KHoCSIIntStatus, KHtCSIIntStatusRxTrgIE); + + } // end of reception processing.. + } + +// constructor 1-st stage +DCsiChannelMaster::DCsiChannelMaster(TInt aChannelNumber, TBusType aBusType, TChannelDuplex aChanDuplex) : + DIicBusChannelMaster(aBusType, aChanDuplex), // !!call overloaded base class constructor.. + iTransferEndDfc(TransferEndDfc, this, KCsiDfcPriority), + iHwGuardTimer(TimeoutCallback, this) + { + iHwTimeoutValue = -1; + iSSPin = 0; + iChannelNumber = aChannelNumber; //Set the iChannelNumber of the Base Class + iState = EIdle; + __KTRACE_OPT(KIIC, Kern::Printf("DCsiChannelMaster::DCsiChannelMaster: iChannelNumber = %d", iChannelNumber)); + } + +// 2nd stage construction.. +TInt DCsiChannelMaster::DoCreate() + { + __KTRACE_OPT(KIIC, Kern::Printf("\nDCsiChannelMaster::DoCreate() ch: %d \n", iChannelNumber)); //__THREAD_AND_CPU; + + TInt32 interruptId; + TUint32 channelBase; + + HCR::TSettingId settingId; + settingId.iCat = KHcrCat_MHA_Interrupt; + + HCR::TSettingId channelBaseId; + channelBaseId.iCat = KHcrCat_MHA_HWBASE; + + TInt r = KErrNone; + switch(iChannelNumber) + { + case 0: + settingId.iKey = KHcrKey_Interrupt_CSI0; + channelBaseId.iKey = KHcrKey_HwBase_CSI0; + break; + case 1: + settingId.iKey = KHcrKey_Interrupt_CSI1; + channelBaseId.iKey = KHcrKey_HwBase_CSI1; + break; + default: + __KTRACE_OPT(KIIC, Kern::Printf("Wrong ChannelNumber specified (%d)", iChannelNumber)); + return KErrArgument; + } + + r = HCR::GetUInt(channelBaseId, channelBase); + iChannelBase = channelBase; + + if(r != KErrNone) + { + __KTRACE_OPT(KIIC, Kern::Printf("Failed to read HCR setting for category = %d and key = %d\n", channelBaseId.iCat, channelBaseId.iKey)); + return r; + } + + r = HCR::GetInt(settingId, interruptId); + if(r != KErrNone) + { + __KTRACE_OPT(KIIC, Kern::Printf("Failed to read HCR setting for category = %d and key = %d\n", settingId.iCat, settingId.iKey)); + return r; + } + + //Read the timeout value from HCR + //The value will not be changed during transaction, so it needs to be read only once from HCR + if(iHwTimeoutValue == -1) + { + // csiTimeout values was not yet read from HCR; read it + HCR::TSettingId settingId; + settingId.iCat = KHcrCat_HWServ_CSI; + settingId.iKey = KHcrKey_CSI_Timeout; + r = HCR::GetInt(settingId, iHwTimeoutValue); + if(r != KErrNone) + { + __KTRACE_OPT(KIIC, Kern::Printf("Failed to read HCR setting for category = %d and key = %d\n", settingId.iCat, settingId.iKey)); + return r; + } + } + + + // Create kernel DFCQ (thread) for the driver.. + if(!iDfcQ) + { + TBuf8 threadName (KSpiThreadName); + threadName.AppendNum(iChannelNumber); + TDynamicDfcQue* dynamicDfcQ; + r = Kern::DynamicDfcQCreate(dynamicDfcQ, KSpiThreadPriority, threadName); + if(r != KErrNone) + { + __KTRACE_OPT(KIIC, Kern::Printf("DFC Queue creation failed, ch: %d, r = %d\n", iChannelNumber, r)); + return r; + } + iDfcQ = dynamicDfcQ; + } + + // PIL Base class initialization. This must!! be called prior to SetDfcQ(iDfcQ) .. + r = Init(); + if(r == KErrNone) + { + // set iDFCQ + SetDfcQ(iDfcQ); // base class.. + iTransferEndDfc.SetDfcQ(iDfcQ); // transfer-end DFC + +#ifdef CPU_AFFINITY_ANY + NKern::ThreadSetCpuAffinity((NThread*)(iDfcQ->iThread), KCpuAffinityAny); +#endif + + // Bind the Interrupt. + + iInterruptId = Interrupt::Bind(interruptId, CsiIsr, this); + + // this returns interruptId or error code(err < 0) + if(iInterruptId < KErrNone) + { + __KTRACE_OPT(KIIC, Kern::Printf("ERROR: InterruptBind error.. %d", r)); + r = iInterruptId; + iInterruptId = 0; + } + } + + return r; + } + +// static method used to construct the DCsiChannelMaster object. +// Export the channel creating function for client use in controller-less mode +#ifdef STANDALONE_CHANNEL +EXPORT_C +#endif +DCsiChannelMaster* DCsiChannelMaster::New(TInt aChannelNumber, const TBusType aBusType, const TChannelDuplex aChanDuplex) + { + __KTRACE_OPT(KIIC, Kern::Printf("DCsiChannelMaster::NewL(): aChannelNumber = %d, BusType =%d", aChannelNumber, aBusType)); + DCsiChannelMaster *pChan = new DCsiChannelMaster(aChannelNumber, aBusType, aChanDuplex); + + TInt r = KErrNoMemory; + + if(pChan) + { + r = pChan->DoCreate(); + } + if(r != KErrNone) + { + delete pChan; + pChan = NULL; + } + return pChan; + } + +#ifdef STANDALONE_CHANNEL +DCsiChannelMaster::~DCsiChannelMaster() + { + // This destructor will only be called in controller-less mode, when iDfcQ is a TDynamicDfcQ, + // In here, detroy the dfc queue and unbind the interrupt for next channel creation + + // stop the Hardware + // clear CISE bit..(disables CSI) + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, KHtCSIModeEnable, 0); + + // set CSIRST bit.. + AsspRegister::Modify32(iChannelBase + KHoCSIControl, 0, KHtCSIControlCSIRst); + + if(iInterruptId) + { + Interrupt::Unbind(iInterruptId); + } + if(iDfcQ) + { + ((TDynamicDfcQue*)iDfcQ)->Destroy(); + } + } +#endif + +// this method compares if the previous transaction header and slave-select(chip-select) pin are different +// If configuration is the same - HW will not be re-initialized. It also makes a copy of the new header +// and new pin number used to configure the interface. +TBool DCsiChannelMaster::TransConfigDiffersFromPrev() + { + TConfigSpiBufV01* headerBuf = (TConfigSpiBufV01*) (GetTransactionHeader(iCurrTransaction)); + TConfigSpiV01 &spiHeader = (*headerBuf)(); + + // the busId - has a SlaveAddress which in the case of SPI is a SlaveSelect pin (GPIO pin number) + TUint32 busId = ((TIicBusTransaction*)iCurrTransaction)->GetBusId(); + + // get the slave address + TUint16 csPin; + csPin = GET_SLAVE_ADDR(busId); + + // compare it to the previous configuration.. + if(csPin != iSSPin || + spiHeader.iWordWidth != iSpiHeader.iWordWidth || + spiHeader.iClkSpeedHz != iSpiHeader.iClkSpeedHz || + spiHeader.iClkMode != iSpiHeader.iClkMode || + spiHeader.iTimeoutPeriod != iSpiHeader.iTimeoutPeriod || + spiHeader.iBitOrder != iSpiHeader.iBitOrder || + spiHeader.iTransactionWaitCycles != iSpiHeader.iTransactionWaitCycles || + spiHeader.iSSPinActiveMode != iSpiHeader.iSSPinActiveMode) + { + iSSPin = csPin; // copy CsPin number. + iSpiHeader = spiHeader; // copy the new config params +#ifdef _DEBUG + DumpConfiguration(spiHeader, iSSPin); +#endif + return ETrue; + } + + return EFalse; + } + +// Validates various fields in the transaction header +// this pure-virtual method is called by the PIL in the context of the +// client's thread - whenever he makes a call to QueueTransaction(). +TInt DCsiChannelMaster::CheckHdr(TDes8* aHdrBuff) + { + TInt r = KErrNone; + + if(!aHdrBuff) + { + r = KErrArgument; + } + else + { + TConfigSpiBufV01* headerBuf = (TConfigSpiBufV01*) aHdrBuff; + TConfigSpiV01 &spiHeader = (*headerBuf)(); + + if(spiHeader.iTransactionWaitCycles > 15) // (can be 0 - 15) + { + __KTRACE_OPT(KIIC, Kern::Printf("iTransactionWaitCycles not supported")); + r = KErrNotSupported; + } + else + { + if(spiHeader.iWordWidth != ESpiWordWidth_8 && + spiHeader.iWordWidth != ESpiWordWidth_16) + { + __KTRACE_OPT(KIIC, Kern::Printf("iWordWidth not supported")); + r = KErrNotSupported; + } + else + { + if(spiHeader.iClkSpeedHz != 130000 && + spiHeader.iClkSpeedHz != 260000 && + spiHeader.iClkSpeedHz != 521000 && + spiHeader.iClkSpeedHz != 1040000 && + spiHeader.iClkSpeedHz != 2080000 && + spiHeader.iClkSpeedHz != 4170000 && + spiHeader.iClkSpeedHz != 16670000) + { + __KTRACE_OPT(KIIC, Kern::Printf("iClock not supported")); + r = KErrNotSupported; + } + } + } + } + __KTRACE_OPT(KIIC, Kern::Printf("DCsiChannelMaster::CheckHdr() r %d", r)); + return r; + } + +// Initializes the hardware with the data provided in the transaction and slave-address field +TInt DCsiChannelMaster::ConfigureInterface() + { + __KTRACE_OPT(KIIC, Kern::Printf("ConfigureInterface()")); + + HCR::TSettingId settingId; + + // CSI initialization procedure: + // 1. clear CISE bit.. + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, KHtCSIModeEnable, 0); + + // 2. wait until CIS_MODE.bit0 (CSOT) changes to 0 + // start the GuardTimer before while-loop.. + iTransactionStatus = KErrNone; + + iHwGuardTimer.OneShot(NKern::TimerTicks(iHwTimeoutValue)); + + while((iTransactionStatus == KErrNone) && + AsspRegister::Read32(iChannelBase + KHoCSIModeControl) & KHtCSIModeTransferState); + + // check if the the guard timer or transaction timer hasn't expired.. + if(iTransactionStatus != KErrNone) + { + return KErrGeneral; + } + else + { + iHwGuardTimer.Cancel(); + } + + // 3. set CSIRST bit.. + AsspRegister::Modify32(iChannelBase + KHoCSIControl, 0, KHtCSIControlCSIRst); + + // 4. set KHoCSIClockSelect register.. + TUint32 val = 0; + + // CKP - ClocK Polarity (bit 4) 0: initial value is high, 1: initial val is low + // DAP - Clock phase select (bit 3) 0: 180 degree delay, 1: 0 degree delay + // @** don't use DAP=1 when iClock set to KHCSIClockValPCLKdiv4 (HW bug..see SoC errata) + switch(iSpiHeader.iClkMode) + { + case ESpiPolarityLowRisingEdge: // Active high, odd edges + val = KHtCSIClockSelectCKP; // CKP 1, DAP 0 + break; + case ESpiPolarityLowFallingEdge: // Active high, even edges + val = KHtCSIClockSelectCKP | // CKP 1, DAP 1 + KHtCSIClockSelectDAP; + break; + + case ESpiPolarityHighFallingEdge: // Active low, odd edges + val = 0; // CKP 0, DAP 0 + break; + + case ESpiPolarityHighRisingEdge: // Active low, even edges + val = KHtCSIClockSelectDAP; // CKP 0, DAP 1 + break; + default: + break; // there's no default..no other value can be specified as it's an enum ;) + } + + // set the clock.. + switch(iSpiHeader.iClkSpeedHz) + { + case 130000: + val |= KHCSIClockValPCLKdiv512; // 1/512 PCLK (master mode) 130 kHz + break; + case 260000: + val |= KHCSIClockValPCLKdiv256; // 1/256 PCLK (master mode) 260 kHz + break; + case 521000: + val |= KHCSIClockValPCLKdiv128; // 1/128 PCLK (master mode) 521 kHz + break; + case 1040000: + val |= KHCSIClockValPCLKdiv64; // 1/64 PCLK (master mode) 1.04 MHz + break; + case 2080000: + val |= KHCSIClockValPCLKdiv32; // 1/32 PCLK (master mode) 2.08 MHz + break; + case 4170000: + val |= KHCSIClockValPCLKdiv16; // 1/16 PCLK (master mode) 4.17 MHz + break; + case 16670000: + if(val & KHtCSIClockSelectDAP) // see @** + { + __KTRACE_OPT(KIIC, Kern::Printf("Unsupported CLK/Clock mode")); + return KErrArgument; + } + val |= KHCSIClockValPCLKdiv4; // 1/4 PCLK (master mode) 16.67 MHz + break; + default: + return KErrNotSupported; + } + + // set transaction wait time.. + val |= (0xf & iSpiHeader.iTransactionWaitCycles) << KHsCSIModeTWait; + + // and finally update the register + AsspRegister::Write32(iChannelBase + KHoCSIClockSelect, val); + + // 5. clear KHtCSIControlCSIRst bit.. + AsspRegister::Modify32(iChannelBase + KHoCSIControl, KHtCSIControlCSIRst, 0); + + // 6. Set Mode Control register: + // Transmission and reception mode + val = KHtCSIModeTrEnable; + + // Select transmit data length (8/16 bits) + if(iSpiHeader.iWordWidth == ESpiWordWidth_16) + { + iWordSize = 2; + val |= KHtCSIModeDataLen; + } + else + { + iWordSize = 1; + } + + // Select Transfer direction (if set-LSB first) + if(iSpiHeader.iBitOrder == ELsbFirst) + { + val |= KHtCSIModeTransferDir; + } + + // update the register + AsspRegister::Write32(iChannelBase + KHoCSIModeControl, val); + + // 7. Set FIFO trigger levels + TUint8 csiFifoRxTrigerLvl; + + settingId.iCat = KHcrCat_HWServ_CSI; + settingId.iKey = KHcrKey_CSI_FifoRxTrigerLvl; + + TInt r = HCR::GetUInt(settingId, csiFifoRxTrigerLvl); + if(r != KErrNone) + { + __KTRACE_OPT(KIIC, Kern::Printf("Failed to read HCR setting for category = %d and key = %d\n", settingId.iCat, settingId.iKey)); + return r; + } + AsspRegister::Write32(iChannelBase + KHoCSIFifoTrgLvl, (csiFifoRxTrigerLvl << KHsCSIRxFifoTrgLvl)); + + // 8. Clear all interrupts + AsspRegister::Write32(iChannelBase + KHoCSIIntStatus, KInterruptsAll); + + // 9. Set RxTrig permission and enable TEnd and RxTrg interrupts + AsspRegister::Write32(iChannelBase + KHoCSIControl, KHtCSIControlRxTrgEn | + KHtCSIControlTEndIE | + KHtCSIControlRxTrgIE); + + // 10. finally set CSIE bit + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, 0, KHtCSIModeEnable); + + // enable and configure GPIO pin - it is CS Pin used for the transmission.. + // if specified different (e.g. 0) - iSSPin will be ignored during the transmission.. + if(iSSPin < 1 || iSSPin > 32) // can be 1 - 32 + { + __KTRACE_OPT(KIIC, Kern::Printf("Wrong pin number specified()")); + return KErrArgument; + } + else + { + GPIO::SetPinMode(iSSPin, GPIO::EEnabled); + GPIO::SetPinDirection(iSSPin, GPIO::EOutput); + GPIO::SetDebounceTime(iSSPin, 0); + + // and set active high bit (KtCSPinHigh) + if(iSpiHeader.iSSPinActiveMode == ESpiCSPinActiveHigh) + { + iSSPinActiveStateOn = GPIO::EHigh; + iSSPinActiveStateOff = GPIO::ELow; + } + else + { + iSSPinActiveStateOn = GPIO::ELow; + iSSPinActiveStateOff = GPIO::EHigh; + } + } + + // clear KHtCSIModeEnable.. it will be set to trigger the transmission in DoTransfer() + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, KHtCSIModeEnable, 0); + + return KErrNone; + } + +// This method starts data transfer - filling the Transmit FIFO and enabling the device (CSIE bit) +TInt DCsiChannelMaster::DoTransfer(TInt8 *aBuff, TUint aNumOfBytes) + { + __KTRACE_OPT(KIIC, Kern::Printf("\nDCsiChannelMaster::DoTransfer()")); + __KTRACE_OPT(KIIC, Kern::Printf("Receiving %d, Transmitting %d", iOperation.iOp.iIsReceiving, iOperation.iOp.iIsTransmitting)); + + if(aNumOfBytes == 0) // wanted to transfer an empty buffer?? + { + return KErrArgument; + } + + // store current Tx buffer addresses - to use them later in the ISR, + // when re-filling the buffer if its level drops down to the threshold value.. + iTxData = aBuff; + iTxDataEnd = (TInt8*) (aBuff + aNumOfBytes); + __KTRACE_OPT(KIIC, Kern::Printf("Tx: Start: %x, End %x, bytes %d\n\n", iTxData, iTxDataEnd, aNumOfBytes)); + + // ensure, we won't be sending until we've filled up the FIFO.. + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, KHtCSIModeEnable, 0); + + // clean the FIFO.. + AsspRegister::Write32(iChannelBase + KHoCSIOFifoL, 0); + + // if we are transmitting - Add data to the FIFO.. + if(iOperation.iOp.iIsTransmitting) + { + // Set mode to transmission and reception (Set TRMD) + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, 0, KHtCSIModeTrEnable); + + while(AsspRegister::Read32(iChannelBase + KHoCSIOFifoL) < KHwCSIFifoLMax && // until FIFO not full.. + iTxData != iTxDataEnd) // or whole data has been copied. + { + // copy data to the FIFO.. + TUint16 val; + + // in 16bit mode we need to write two bytes as once MSB first.. + if(iWordSize > 1) + { + val = (*iTxData) << 8; // MSB shifted up.. + val |= *(iTxData + 1) & 0xff; // LSB.. + } + else + { + val = *iTxData; + } + + // write this value to the register.. + AsspRegister::Write32(iChannelBase + KHoCSIOFifo, val); + + // increment the pointer. + iTxData += iWordSize; + } + } + else // we are starting receive transfer only.. + { + // Set mode to reception only (clear TRMD) + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, KHtCSIModeTrEnable, 0); + } + + // change the SS line status - start of the transmission. This should be set back to high - after + // the transmission has been finished (iTransferEndDfc) + GPIO::SetOutputState(iSSPin, iSSPinActiveStateOn); + + // enable interrupts.. + Interrupt::Enable(iInterruptId); + + // enable transmission..this will trigger the HW to start the transmission.. + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, 0, KHtCSIModeEnable); + + return KErrNone; + } + +// this method starts the given transfer.. +TInt DCsiChannelMaster::StartTransfer(TIicBusTransfer* aTransferPtr, TUint8 aType) + { + __KTRACE_OPT(KIIC, Kern::Printf("DCsiChannelMaster::StartTransfer()")); + + TInt r = KErrNone; + + switch(aType) + { + case TIicBusTransfer::EMasterWrite: + { + __KTRACE_OPT(KIIC, Kern::Printf("Starting EMasterWrite, duplex=%d", iFullDTransfer)); + + const TDes8* aBufPtr = GetTferBuffer(aTransferPtr); + + __KTRACE_OPT(KIIC, Kern::Printf("Length %d, iWordSize %d", aBufPtr->Length(), iWordSize)); + + // set this flag - to indicate, that we'll be transmitting the data. + // if this is set to 0 prior to calling to DoTransfer() - only '0'(or KValueSentOnRead) values will be + // sent out of the interface (e.g. if only receiving from the slave - to generate the clock) + iOperation.iOp.iIsTransmitting = ETrue; + + // initiate the transmission.. + r = DoTransfer((TInt8 *) aBufPtr->Ptr(), aBufPtr->Length()); + + if(r != KErrNone) + { + __KTRACE_OPT(KIIC, Kern::Printf("Starting Write filed, r = %d", r)); + } + break; + } + case TIicBusTransfer::EMasterRead: + { + __KTRACE_OPT(KIIC, Kern::Printf("Starting EMasterRead, duplex=%x", iFullDTransfer)); + + // store the current address and ending address for Reception- to use them later in the ISR and DFC + const TDes8* aBufPtr = GetTferBuffer(aTransferPtr); + + iRxData = (TInt8*) aBufPtr->Ptr(); + iRxDataEnd = (TInt8*) (iRxData + aBufPtr->Length()); + + __KTRACE_OPT(KIIC, Kern::Printf("Rx: Start: %x, End %x, bytes %d", iRxData, iRxDataEnd, aBufPtr->Length())); + + // set the flag - that we're going to receive the data.. + iOperation.iOp.iIsReceiving = ETrue; + + // if this is half-duplex transfer.. (read-only) + // we still need to transmit '0' to generate CLK and SS signals for the Slave + if(!iFullDTransfer) + { + // make sure transmitting flag is cleared + iOperation.iOp.iIsTransmitting = EFalse; + + // set pointers - as if we're transmitting the same amount of data.. + r = DoTransfer((TInt8 *) aBufPtr->Ptr(), aBufPtr->Length()); + } + } + break; + default: + { + __KTRACE_OPT(KIIC, Kern::Printf("Unsupported TrasactionType %x", aType)); + r = KErrArgument; + break; + } + } + + return r; + } + +// calling this method whenever a transfer has been finished - will process all transfers in the transaction +TInt DCsiChannelMaster::ProcessNextTransfers() + { + // transfers are queued in linked list.. so just go through that list and start them + __KTRACE_OPT(KIIC, Kern::Printf("DCsiChannelMaster::ProcessNextTransfers(),BUSY=%d", iState)); + + // clear flags.. + iOperation.iValue = TCsiOperationType::ENop; + + // in both cases - full-duplex - or simple half-duplex + // we need to flush the buffers for the transmission: + AsspRegister::Write32(iChannelBase + KHoCSIIFifoL, 0); // write 0 to FIFOL will drop data + AsspRegister::Write32(iChannelBase + KHoCSIOFifoL, 0); // write 0 to FIFOL will drop data + + // if this is the first transfer in the transaction..(called from DoCreate) + if(iState == EIdle) + { + // Get the pointer to half-duplex transfer object.. + iHalfDTransfer = GetTransHalfDuplexTferPtr(iCurrTransaction); + + // Get the pointer to full-duplex transfer object.. + iFullDTransfer = GetTransFullDuplexTferPtr(iCurrTransaction); + + // from now on - our state is EBusy. + iState = EBusy; + + // kick-off the transaction timer.. + // it's default handler, run in ISR context will change the iTransactionStatus + // and queue TranferEndDfc (in the case if it wasn't queued) - this DFC + // will then finish transfer and report this error to the PIL. + __ASSERT_DEBUG(iSpiHeader.iTimeoutPeriod > 0, Kern::Fault("NE1_TB SPI: timeout value not set,line: %d", __LINE__)); + __KTRACE_OPT(KIIC, Kern::Printf("Timeout for transaction %d", iSpiHeader.iTimeoutPeriod)); + iTransactionStatus = KErrNone; + // Initiate the timer for the transaction. When it expires - PIL will call + // HandleSlaveTimeout() - which will stop the HW operations.. + StartSlaveTimeOutTimer(iSpiHeader.iTimeoutPeriod); + // When the KIIC trace flag is enabled, we need cancel the transaction timeout, + // so that debug traces don't cause slave timer expiration. + __KTRACE_OPT(KIIC, CancelTimeOut()); + + } + else + // We continue with next transfer in the transaction..(Called from TransferEndDfc) + { + // Get the pointer the next half-duplex transfer object.. + iHalfDTransfer = GetTferNextTfer(iHalfDTransfer); + + // Get the pointer to the next half-duplex transfer object.. + if(iFullDTransfer) + { + iFullDTransfer = GetTferNextTfer(iFullDTransfer); + } + } + + // all of the transfers were completed, just notify the PIL and return. + // (if either Rx or Tx has not finished properly ExitComplete() would have been called + // from TransferEndDfc if there was an error during the transfer) + TInt r = KErrNone; + if(!iFullDTransfer && !iHalfDTransfer) + { + __KTRACE_OPT(KIIC, Kern::Printf("All transfers completed successfully")); + // complete the request.. + ExitComplete(KErrNone); + } + else + { + // start transfers.. + // if this is full-duplex transfer - we need to Start EMasterRead transfer first + // this is because buffer pointers and flags for this transfer type must be initialized + // prior to starting EMasterWrite (which always triggers the transmission start) + TInt8 hDTrType = (TInt8) GetTferType(iHalfDTransfer); + + if(iFullDTransfer) + { + // if iHalfDTransfer is EMasterRead - start it first.. + if(hDTrType == TIicBusTransfer::EMasterRead) + { + r = StartTransfer(iHalfDTransfer, TIicBusTransfer::EMasterRead); + if(r != KErrNone) + { + return r; + } + r = StartTransfer(iFullDTransfer, TIicBusTransfer::EMasterWrite); + } + else // hDTrType == TIicBusTransfer::EMasterWrite) + { + r = StartTransfer(iFullDTransfer, TIicBusTransfer::EMasterRead); + if(r != KErrNone) + { + return r; + } + r = StartTransfer(iHalfDTransfer, TIicBusTransfer::EMasterWrite); + } + } + else + // this is normal halfDuplex transfer - so just start it + { + r = StartTransfer(iHalfDTransfer, hDTrType); + } + } + return r; + } + +// Gateway function for PSL implementation - this method is an entry point - it is called by the PIL +// to initiate the transaction. After finishing it's processing PSL calls CompleteRequest(error_status) +TInt DCsiChannelMaster::DoRequest(TIicBusTransaction* aTransaction) + { + __KTRACE_OPT(KIIC, Kern::Printf("DCsiChannelMaster::DoRequest (aTransaction=0x%x)\n", aTransaction)); + + // Check, if pointers are not NULL.. + if(!aTransaction || !GetTransactionHeader(aTransaction)) + { + return KErrArgument; + } + + // Make sure if the PIL doesn't try to start another one- before we've confirmed the previous one.. + if(iState != EIdle) + { + return KErrInUse; + } + + // copy pointer to the transaction.. + iCurrTransaction = aTransaction; + + // check, if Hardware needs re-configuration + // (i.e. this transaction and SlaveAddress (iSSPin) are the same as for the previous one) + TInt r = KErrNone; + if(TransConfigDiffersFromPrev()) + { + r = ConfigureInterface(); + if(r != KErrNone) + { + iSSPin = 0; + return r; + } + } + + // start processing transfers of this transaction. + r = ProcessNextTransfers(); + + return r; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/csi/csi_master.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/csi/csi_master.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,133 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + + +#ifndef __CSI_MASTER_H_ +#define __CSI_MASTER_H_ + +#include +#include +#include +#include "csi_psl.h" + +_LIT(KSpiThreadName,"SpiChannelThread_"); + +const TInt KCsiDfcPriority = 0; // Arbitrary, can be 0-7, 7 highest +const TInt KSpiThreadPriority = 24; + +// DCsiChannelMaster class declaration: +class DCsiChannelMaster: public DIicBusChannelMaster + { +public: +#ifdef STANDALONE_CHANNEL + IMPORT_C +#endif + static DCsiChannelMaster* New(TInt aChannelNumber, const TBusType aBusType, const TChannelDuplex aChanDuplex); + + // gateway function for PSL implementation + virtual TInt DoRequest(TIicBusTransaction* aTransaction); + + // overloaded constructor.. + DCsiChannelMaster(TInt aChannelNumber, const TBusType aBusType, const TChannelDuplex aChanDuplex); +#ifdef STANDALONE_CHANNEL + ~DCsiChannelMaster(); +#endif +protected: + // overriders for base pure-virtual methods.. + virtual TInt DoCreate(); // 2nd stage construction. + virtual TInt CheckHdr(TDes8* aHdr); + virtual TInt HandleSlaveTimeout(); + +private: + // other internal methods + TInt ConfigureInterface(); + TBool TransConfigDiffersFromPrev(); + TInt DoTransfer(TInt8 *aBuff, TUint aNumOfBytes); + TInt StartTransfer(TIicBusTransfer* aTransferPtr, TUint8 aType); + TInt ProcessNextTransfers(); + void ExitComplete(TInt aErr, TBool aComplete = ETrue); + + // Dfc/timeout Callback functions + static void TransferEndDfc(TAny* aPtr); + static void TransferTimeoutDfc(TAny* aPtr); + static void TimeoutCallback(TAny* aPtr); + + // ISR handler. + static void CsiIsr(TAny* aPtr); + + // DFc for Handling Transfer complete + TDfc iTransferEndDfc; + + // flags indicating transmission/operation + TCsiOperationType iOperation; + + // granularity.. + TUint8 iWordSize; + + // to store currently used CS pin number + TUint8 iSSPin; + + // current state + enum TMyState + { + EIdle, + EBusy + }; + TMyState iState; + + // as implementation is common/generic for both channels + // store base register address and interruptID + TUint iChannelBase; + TInt iInterruptId; + + // pointers used to store current transfers information + TIicBusTransfer* iHalfDTransfer; + TIicBusTransfer* iFullDTransfer; + + // and current transaction. + TIicBusTransaction* iCurrTransaction; + + // pointers to buffers used to transfer data from/to... + TInt8 *iTxData; + TInt8 *iRxData; + TInt8 *iTxDataEnd; + TInt8 *iRxDataEnd; + + // Timer to guard 'while' loops.. + NTimer iHwGuardTimer; + // guard-timer timeout value (in ms) + TInt32 iHwTimeoutValue; + + // status of the transaction + volatile TInt iTransactionStatus; + + // to store current configuration (for current transaction) + TConfigSpiV01 iSpiHeader; + + // and its active/inactive state (can be active on high or low) + GPIO::TGpioState iSSPinActiveStateOff; + GPIO::TGpioState iSSPinActiveStateOn; + + // if the Master is a part of DIicBusChannelMasterSlave object, + // we allow the friend class to unbind master's ISR - and register its own + // for the time the channel is captured by the Slave. + friend class DCsiChannelSlave; + }; + +#endif //__CSI_MASTER_H_ diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/csi/csi_psl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/csi/csi_psl.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,146 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifdef STANDALONE_CHANNEL +#include +#else +#include +#endif + +#include +#include +#include "csi_psl.h" + +#ifdef MASTER_MODE +#include "csi_master.h" +#endif +#ifdef SLAVE_MODE +#include "csi_slave.h" +#endif + +#include "hcrconfig.h" +#include "hcrconfig_csi.h" + +// table of pointers to the channels - to be filled with pointers to channels +// and used to register these channels with the Bus Controller +// (definition) +DIicBusChannel** ChannelPtrArray; + +// EXTENSION DLL ENTRY POINT +DECLARE_EXTENSION_WITH_PRIORITY(BUS_IMPLMENTATION_PRIORITY) + { + TInt r = KErrNone; +#ifndef STANDALONE_CHANNEL + + HCR::TSettingId settingId; + settingId.iCat = KHcrCat_HWServ_CSI; + settingId.iKey = KHcrKey_CSI_NumOfChannels; + TInt32 csiNumOfChannels; + + r = HCR::GetInt(settingId, csiNumOfChannels); + if(r != KErrNone) + { + __KTRACE_OPT(KIIC, Kern::Printf("Failed to read HCR setting for category = %d and key = %d\n", settingId.iCat, settingId.iKey)); + return r; + } + ChannelPtrArray = new DIicBusChannel*[csiNumOfChannels]; + +#ifdef MASTER_MODE +#ifndef SLAVE_MODE + // If only MASTER_MODE is declared - Create all as DCsiChannelMaster channels + __KTRACE_OPT(KIIC, Kern::Printf("\n\nCreating DCsiChannelMaster only")); + + DIicBusChannel* chan = NULL; + for (TInt i = 0; i < csiNumOfChannels; ++i) + { + chan = DCsiChannelMaster::New(i, DIicBusChannel::ESpi, DIicBusChannel::EFullDuplex); + if (!chan) + { + return KErrNoMemory; + } + ChannelPtrArray[i] = chan; + } + +#else /*SLAVE_MODE*/ + // both - Master and Slave channels.. or MasterSlaveChannels.. + // for now, create channel 0 as Master, and channel 1 as a Slave. + __KTRACE_OPT(KIIC, Kern::Printf("\n\nCreating Master and Slave")); + + DIicBusChannel* chan = NULL; + // create channel 0 - as master.. + chan = DCsiChannelMaster::New(0, DIicBusChannel::ESpi, DIicBusChannel::EFullDuplex); + if (!chan) + { + return KErrNoMemory; + } + ChannelPtrArray[0] = chan; + + // and created channel 1 - as slave.. + chan = DCsiChannelSlave::New(1, DIicBusChannel::ESpi, DIicBusChannel::EFullDuplex); + if (!chan) + { + return KErrNoMemory; + } + ChannelPtrArray[1] = chan; + +#endif /*SLAVE_MODE*/ +#else /*MASTER_MODE*/ + +#ifdef SLAVE_MODE + // If only SLAVE_MODE is declared - Create all as DCsiChannelMaster channels + __KTRACE_OPT(KIIC, Kern::Printf("\n\nCreating DCsiChannelSlave only")); + + DIicBusChannel* chan = NULL; + for (TInt i = 0; i < csiNumOfChannels; ++i) + { + chan = DCsiChannelSlave::New(i, DIicBusChannel::ESpi, DIicBusChannel::EFullDuplex); + if (!chan) + { + return KErrNoMemory; + } + ChannelPtrArray[i] = chan; + } + +#endif +#endif /*MASTER_MODE*/ + + // Register them with the Bus Controller + r = DIicBusController::RegisterChannels(ChannelPtrArray, csiNumOfChannels); +#endif/*STANDALONE_CHANNEL*/ + + return r; + } + +// helper function - to dump the supplied configuration +#ifdef _DEBUG +void DumpConfiguration(const TConfigSpiBufV01& spiHeader, TInt aCsPin) + { +#ifdef DUMP_CONFIG + __KTRACE_OPT(KIIC, Kern::Printf("new configuration:\n")); + __KTRACE_OPT(KIIC, Kern::Printf("iWordWidth %d", spiHeader().iWordWidth)); + __KTRACE_OPT(KIIC, Kern::Printf("iClkSpeedHz: %d", spiHeader().iClkSpeedHz)); + __KTRACE_OPT(KIIC, Kern::Printf("iClkMode %d", spiHeader().iClkMode)); + __KTRACE_OPT(KIIC, Kern::Printf("iTimeoutPeriod %d", spiHeader().iTimeoutPeriod)); + __KTRACE_OPT(KIIC, Kern::Printf("iBitOrder %d", spiHeader().iBitOrder)); + __KTRACE_OPT(KIIC, Kern::Printf("iTransactionWaitCycles %d", spiHeader().iTransactionWaitCycles)); + __KTRACE_OPT(KIIC, Kern::Printf("iSSPinActiveMode %d", spiHeader().iSSPinActiveMode)); + __KTRACE_OPT(KIIC, Kern::Printf("csPin %d\n", aCsPin)); +#endif + } +#endif + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/csi/csi_psl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/csi/csi_psl.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#ifndef __CSI_PSL_H__ +#define __CSI_PSL_H__ + +const TUint KInterruptsAll = 0xf111; + +extern TInt32 csiTimeoutValue; + +// table of pointers to the channels - to be filled with pointers to channels +// and used to register these channels with the Bus Controller +// (declaration-to be included by master/slave) +extern DIicBusChannel** ChannelPtrArray; + +// helper function - to dump the supplied configuration +#ifdef _DEBUG +void DumpConfiguration(const TConfigSpiBufV01& spiHeader, TInt aCsPin); +#endif + +// a bit-field to store the current mode of operation +struct TCsiOperationType + { + enum TOperation + { + ENop = 0x00, + ETransmitOnly = 0x01, + EReceiveOnly = 0x02, + ETransmitReceive = 0x03 + }; + + struct TOp + { + TUint8 iIsTransmitting : 1; + TUint8 iIsReceiving : 1; + TUint8 iRest : 6; + }; + + union + { + TOp iOp; + TUint8 iValue; + }; + }; + +#endif /*__CSI_PSL_H__*/ diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/csi/csi_slave.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/csi/csi_slave.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,879 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include +#include +#include +#include "csi_psl.h" +#include "csi_slave.h" + +#include "hcrconfig.h" +#include "hcrconfig_csi.h" + +// the timeout period to wait for a response from the client. +// We can't predict the frequency, at which the Master will be sending us data, +// it can be from 130kHz (which is 16,25bytes/ms) up to 16,67MHz(2083 bytes/ms). +// Timeout is set for the slowest transfer - for the time that the 32 bytes Tx FIFO would be emptied +// (Rx FIFO filled), so 2ms. +const TInt KClientWaitTime = 2; // when debugging might set up to KMaxWaitTime + +// set of interrupt flags used by the driver +const TUint32 KSlaveInterruptFlags = + KHtCSIControlSSDnIE | // SS signal negative-edge interrupt enable + KHtCSIControlSSUpIE | // SS signal positive-edge interrupt enable + KHtCSIControlTEndIE | + KHtCSIControlRxTrgEn | + KHtCSIControlRxTrgIE; + + +#ifdef __SMP__ +static TSpinLock CsiSpinLock = TSpinLock(TSpinLock::EOrderGenericIrqLow2); +#endif + +// this is call-back for iHwGuard timer. It is called in the ISR context +// if the iHwGuardTimer expires. +// It will change the iTransactionStatus to KErrTimedOut to allow exiting from the while-loop.. +void DCsiChannelSlave::TimeoutCallback(TAny* aPtr) + { + __KTRACE_OPT(KIIC, Kern::Printf("DCsiChannelMaster::TimeoutCallback")); + DCsiChannelSlave *a = (DCsiChannelSlave*) aPtr; + a->iTransactionStatus = KErrTimedOut; + } + + +// this is a static method to be called - when SS line is de-asserted. +// it disabled the interface and interrupts, and then it checks which flags +// need to be specified and then calls NotifyClient using it +void DCsiChannelSlave::NotifyClientEnd(DCsiChannelSlave* aPtr) + { + __KTRACE_OPT(KIIC, Kern::Printf("NotifyClientEnd, iTrigger %x", aPtr->iTrigger)); + + // disable interrupts and the interface.. + AsspRegister::Modify32(aPtr->iChannelBase + KHoCSIModeControl, + KHtCSIModeEnable | KSlaveInterruptFlags, 0); + + // call NotifyClient with xAllBytes (as specified by the Operation) + TInt flag = 0; + if(aPtr->iTrigger & EReceive) + { + flag = ERxAllBytes; + // if received less data, than the buffer size (i.e the Master de-asserted SS line + // before we could fill the whole buffer) - this is the underrun situation + if(aPtr->iRxDataEnd != aPtr->iRxData) + { + __KTRACE_OPT(KIIC, Kern::Printf("Rx Underrun")); + flag |= ERxUnderrun; + } + } + + if(aPtr->iTrigger & ETransmit) + { + flag |= ETxAllBytes; + // if not everything was transferred, i.e. Master de-asserted SS line + // before we could transmit all the data - this is the overrun error.. + if(aPtr->iTxDataEnd != aPtr->iTxData) + { + __KTRACE_OPT(KIIC, Kern::Printf("Tx Overrun")); + flag |= ETxOverrun; + } + } + + aPtr->NotifyClient(flag); + } + +// ISR Handler +void DCsiChannelSlave::CsiIsr(TAny* aPtr) + { + DCsiChannelSlave *a = (DCsiChannelSlave*) aPtr; + TInt intState = 0; + + // read the interrupt flags - to see, what was causing the interrupt.. + TUint32 status = AsspRegister::Read32(a->iChannelBase + KHoCSIIntStatus); + + // SS signal negative-edge interrupt + if (status & KHtCSIIntStatusSSDn) + { + // falling edge.. + TInt pin = AsspRegister::Read32(a->iChannelBase + KHoCSIControl) & KHtCSIControlSSMon; + + // falling edge.. and if pin active at LOW state - this is the beginning + // of the transmission from the Master.. + if (a->iSSPinActiveMode == ESpiCSPinActiveLow) + { + intState = __SPIN_LOCK_IRQSAVE(CsiSpinLock); + if (!pin && !a->iInProgress) + { + a->iInProgress = ETrue; + } + __SPIN_UNLOCK_IRQRESTORE(CsiSpinLock, intState); + } + else + // falling edge.. and if pin active at HIGH state - this is the end + // of the transmission from the Master.. + { + TInt8 notify = EFalse; + intState = __SPIN_LOCK_IRQSAVE(CsiSpinLock); + if (pin && a->iInProgress) + { + a->iInProgress = EFalse; + notify = ETrue; + } + __SPIN_UNLOCK_IRQRESTORE(CsiSpinLock, intState); + + if(notify) + { + a->NotifyClientEnd(a); + return; + } + } + + + // clear KHtCSIIntStatusSSDn interrupt.. + AsspRegister::Write32(a->iChannelBase + KHoCSIIntStatus, KHtCSIIntStatusSSDn); + } + + // SS signal positive-edge interrupt + if (status & KHtCSIIntStatusSSUp) + { + // rising edge.. + TInt pin = AsspRegister::Read32(a->iChannelBase + KHoCSIControl) & KHtCSIControlSSMon; + + // rising edge.. and if pin active at HIGH state - this is the beginning + // of the transmission from the Master.. + if (a->iSSPinActiveMode == ESpiCSPinActiveHigh) + { + intState = __SPIN_LOCK_IRQSAVE(CsiSpinLock); + if (pin && !a->iInProgress) + { + a->iInProgress = ETrue; + } + __SPIN_UNLOCK_IRQRESTORE(CsiSpinLock, intState); + } + else + // rising edge.. and if pin active at LOW state - this is the END + // of the transmission from the Master.. + { + TInt8 notify = EFalse; + + intState = __SPIN_LOCK_IRQSAVE(CsiSpinLock); + if(pin && a->iInProgress) + { + a->iInProgress = EFalse; + notify = ETrue; + } + __SPIN_UNLOCK_IRQRESTORE(CsiSpinLock, intState); + + if(notify) + { + a->NotifyClientEnd(a); + return; + } + } + + // clear KHtCSIIntStatusSSUp interrupt.. + AsspRegister::Write32(a->iChannelBase + KHoCSIIntStatus, KHtCSIIntStatusSSUp); + } + + TInt trigger = 0; + if (status & (KHtCSIIntStatusTEnd | KHtCSIIntStatusRxTrgIE)) + { + intState = __SPIN_LOCK_IRQSAVE(CsiSpinLock); + trigger = a->iTrigger; + __SPIN_UNLOCK_IRQRESTORE(CsiSpinLock, intState); + } + + // process TEND end interrupts + // this ISR happens every time ONE unit has been transfered.. + if (status & KHtCSIIntStatusTEnd) + { + // clear TxEnd interrupt.. + AsspRegister::Write32(a->iChannelBase + KHoCSIIntStatus, KHtCSIIntStatusTEnd); + + if(trigger & ETransmit) + { + if(a->iTxData == a->iTxDataEnd) + { + // if we've moved all the data to the FIFO.. + // notify the PIL with ETxAllBytes | ETxUnderrun; + // (so that - if the Client set ERxUnderrun - he could provide more data to be sent.. + AsspRegister::Modify32(a->iChannelBase + KHoCSIControl, KHtCSIControlTEndIE, 0); + a->NotifyClient(ETxAllBytes | ETxUnderrun); + } + else + { + // if tere's more data to be sent - copy next item to the FIFO window register. + TUint16 val; + + // in 16bit mode we need to read MSB first.. + if(a->iWordSize > 1) + { + val = (*a->iTxData) >> 8; // MSB shifted down.. + val |= *(a->iTxData + 1) & 0xff; // LSB.. + } + else + { + val = *a->iTxData; + } + + // copy the data item to the FIFO window register + AsspRegister::Write32(a->iChannelBase + KHoCSIOFifo, val); + + // increment the pointer.. + a->iTxData += a->iWordSize; + } + } + } //end of TXEnd processing + + // process receive threshold interrupt + if (status & KHtCSIIntStatusRxTrgIE) + { + // read data from the FIFO .. + if(trigger & EReceive) + { + while(AsspRegister::Read32(a->iChannelBase + KHoCSIIFifoL)) + { + // if there's still some place in the buffer - put it into buffer.. + if((a->iRxDataEnd - a->iRxData) >= a->iWordSize) + { + // copy data from the FIFO if tere's more space in the buffer + TUint16 val = AsspRegister::Read32(a->iChannelBase + KHoCSIIFifo); + + // we're big-endian.. (AB).. + // so in 16bit mode we need to read MSB first.. + if(a->iWordSize > 1) + { + *a->iRxData = val >> 8; // MSB shifted down.. + *(a->iRxData + 1) = val & 0xff; // LSB.. + } + else + { + *a->iRxData = val; + } + + // increment the pointer.. + a->iRxData += a->iWordSize; + } + else + { + // overrun, i.e Slave has sent more data than expected by the client + //__KTRACE_OPT(KIIC, Kern::Printf("REND, ERxOverrun")); + AsspRegister::Modify32(a->iChannelBase + KHoCSIControl, KHtCSIControlRxTrgIE, 0); + a->NotifyClient(ERxAllBytes | ERxOverrun); + break; + } + } + } + else + { + // or drop the data, writing 0 to the FIFOL register + AsspRegister::Write32(a->iChannelBase + KHoCSIIFifoL, 0); + } + + // Clear the RxThreshold interrupt + AsspRegister::Write32(a->iChannelBase + KHoCSIIntStatus, KHtCSIIntStatusRxTrgIE); + + } // end of reception processing.. + } + +// overloaded constructor +DCsiChannelSlave::DCsiChannelSlave(TInt aChannelNumber, + const DIicBusChannel::TBusType aBusType, + const DIicBusChannel::TChannelDuplex aChanDuplex) : + DIicBusChannelSlave(aBusType, aChanDuplex, 0), + iHwGuardTimer(TimeoutCallback, this) + { + iHwTimeoutValue = -1; + iChannelNumber = aChannelNumber; + __KTRACE_OPT(KIIC, Kern::Printf("DCsiChannelSlave::DCsiChannelSlave, iChannelNumber = %d\n", iChannelNumber)); + } + +// 2nd stage object construction +TInt DCsiChannelSlave::DoCreate() + { + __KTRACE_OPT(KIIC, Kern::Printf("\nDCsiChannelSlave::DoCreate, ch: %d \n", iChannelNumber)); + + TUint32 channelBase; + + HCR::TSettingId channelBaseId; + channelBaseId.iCat = KHcrCat_MHA_HWBASE; + + TInt r = KErrNone; + switch (iChannelNumber) + { + case 0: + channelBaseId.iKey = KHcrKey_HwBase_CSI0; + break; + case 1: + channelBaseId.iKey = KHcrKey_HwBase_CSI1; + break; + default: + __KTRACE_OPT(KIIC, Kern::Printf("Wrong ChannelNumber specified (%d)", iChannelNumber)); + return KErrArgument; + } + + r = HCR::GetUInt(channelBaseId, channelBase); + iChannelBase = channelBase; + + if(r != KErrNone) + { + __KTRACE_OPT(KIIC, Kern::Printf("Failed to read HCR setting for category = %d and key = %d\n", channelBaseId.iCat, channelBaseId.iKey)); + return r; + } + + //Read the timeout value from HCR + if(iHwTimeoutValue == -1) + { + HCR::TSettingId settingId; + // csiTimeout values was not yet read from HCR; read it + settingId.iCat = KHcrCat_HWServ_CSI; + settingId.iKey = KHcrKey_CSI_Timeout; + + TInt r = HCR::GetInt(settingId, iHwTimeoutValue); + if(r != KErrNone) + { + __KTRACE_OPT(KIIC, Kern::Printf("Failed to read HCR setting for category = %d and key = %d\n", settingId.iCat, settingId.iKey)); + return r; + } + } + + // PIL Base class initialization. + r = Init(); + + // set the unique Slave's iChannelId + // THis, along with the instance count of opened Slave channels - will be returned to the client + // as he captures the Channel (in the referenced aChannelId making an unique ID) - and if the capture is + // successful he refers to this channel using the returned ChannelId. + + // For now, let's just use the combination of iChannelNumber/iChannelBase(register address)) + // This might be later replaced by the call into ConfRep to obtain the iChannelId for the PSL. + iChannelId = 0xffff & (iChannelNumber + iChannelBase); + + return r; + } + +// static method used to construct the DCsiChannelSlave object. +#ifdef STANDALONE_CHANNEL +EXPORT_C +#endif +DCsiChannelSlave* DCsiChannelSlave::New(TInt aChannelNumber, const TBusType aBusType, const TChannelDuplex aChanDuplex) + { + __KTRACE_OPT(KIIC, Kern::Printf("DCsiChannelSlave::NewL(): aChannelNumber = %d, BusType =%d", aChannelNumber, aBusType)); + DCsiChannelSlave *pChan = new DCsiChannelSlave(aChannelNumber, aBusType, aChanDuplex); + + TInt r = KErrNoMemory; + if (pChan) + { + r = pChan->DoCreate(); + } + if (r != KErrNone) + { + delete pChan; + pChan = NULL; + } + + return pChan; + } + +// Validates the various Fields in the transaction header +// THis is a pure virtual.. which.. is never called by the PIL?.. +TInt DCsiChannelSlave::CheckHdr(TDes8* aHdrBuff) + { + TInt r = KErrNone; + + if(!aHdrBuff) + { + r = KErrArgument; + } + else + { + TConfigSpiBufV01* headerBuf = (TConfigSpiBufV01*) aHdrBuff; + TConfigSpiV01 &spiHeader = (*headerBuf)(); + + if(spiHeader.iTransactionWaitCycles > 15) // (can be 0 - 15) + { + __KTRACE_OPT(KIIC, Kern::Printf("iTransactionWaitCycles not supported")); + r = KErrNotSupported; + } + else + { + if(spiHeader.iWordWidth != ESpiWordWidth_8 && + spiHeader.iWordWidth != ESpiWordWidth_16) + { + __KTRACE_OPT(KIIC, Kern::Printf("iWordWidth not supported")); + r = KErrNotSupported; + } + } + } + __KTRACE_OPT(KIIC, Kern::Printf("DCsiChannelSlave::CheckHdr() r %d", r)); + + return r; + } + +void DCsiChannelSlave::ProcessData(TInt aTrigger, TIicBusSlaveCallback* aCb) + { + __KTRACE_OPT(KIIC, Kern::Printf("DCsiChannelSlave::ProcessData(), trigger: %x, in progress %d", aTrigger, iInProgress)); + TInt intState; + + // if NotifyClient was called due to SS line de-assertion.. + TInt inProgress; + intState = __SPIN_LOCK_IRQSAVE(CsiSpinLock); + inProgress = iInProgress; + __SPIN_UNLOCK_IRQRESTORE(CsiSpinLock, intState); + + if(!inProgress && + (aTrigger & (ERxAllBytes | ETxAllBytes))) + { + __KTRACE_OPT(KIIC, Kern::Printf("Finished, cleaning..")); + // we migh be still receiving or transmitting data, so must wait until the end of the transmission + // start the guard timer, which - in case of the following while got stucked - will + // unblock this dfc by changing iTransactionStatus + iTransactionStatus = KErrNone; + + iHwGuardTimer.OneShot(NKern::TimerTicks(iHwTimeoutValue)); + + // active wait until the transfer has finished + while((iTransactionStatus == KErrNone) && + (AsspRegister::Read32(iChannelBase + KHoCSIModeControl) & KHtCSIModeTransferState)); + + // clear CSIE bit.. + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, KHtCSIModeEnable, 0); + + // check if the the guard timer or transaction timer hasn't expired.. + if(iTransactionStatus != KErrNone) + { + __KTRACE_OPT(KIIC, Kern::Printf("CsiChannelMaster::TransferEndDfc(): Transaction timed-out")); + return; + } + else + { + iHwGuardTimer.Cancel(); + } + + // clear internal flags + intState = __SPIN_LOCK_IRQSAVE(CsiSpinLock); + iTrigger = 0; + __SPIN_UNLOCK_IRQRESTORE(CsiSpinLock, intState); + } + + // if the transaction was finished + // NotifyClient() with ERxAllBytes (and)or ETxAllBytes called, when SS pin is de-asserted + // this indicated end of the transmission. Check buffer boundaries, as if Rx or Tx buffers + // provided by the client were bigger - this indicates ERxUnderrun or ETxOverrun - accordingly + // Rx.. + if(aTrigger & ERxAllBytes) + { + __KTRACE_OPT(KIIC, Kern::Printf("Rx Buf: %x", iRxData)); + __KTRACE_OPT(KIIC, Kern::Printf("Rx BufeND: %x", iRxDataEnd)); + + __KTRACE_OPT(KIIC, Kern::Printf("\n\nTxFifo level %d", AsspRegister::Read32(iChannelBase + KHoCSIOFifoL))); + __KTRACE_OPT(KIIC, Kern::Printf("RxFifo level %d\n\n", AsspRegister::Read32(iChannelBase + KHoCSIIFifoL))); + + // clear the internal EReceive flag.. + intState = __SPIN_LOCK_IRQSAVE(CsiSpinLock); + iTrigger &= ~EReceive; + __SPIN_UNLOCK_IRQRESTORE(CsiSpinLock, intState); + + // update the buffer information in the Callback object.. + aCb->SetRxWords(iNumRxWords - ((iRxDataEnd - iRxData) / iWordSize)); + } + + // Tx... + if(aTrigger & ETxAllBytes) + { + __KTRACE_OPT(KIIC, Kern::Printf("Tx Buf: %x", iTxData)); + __KTRACE_OPT(KIIC, Kern::Printf("Tx BufeND: %x", iTxDataEnd)); + + // set the callback's TxWords value + __KTRACE_OPT(KIIC, Kern::Printf("aCb->SetTxWords %d", iNumTxWords - ((iTxDataEnd - iTxData) / iWordSize))); + + // clear the internal ETransmit flag.. + intState = __SPIN_LOCK_IRQSAVE(CsiSpinLock); + iTrigger &= ~ETransmit; + __SPIN_UNLOCK_IRQRESTORE(CsiSpinLock, intState); + + // update the buffer information in the Callback object.. + aCb->SetTxWords(iNumTxWords - ((iTxDataEnd - iTxData) / iWordSize)); + } + + if(aTrigger & EGeneralBusError) + { + __KTRACE_OPT(KIIC, Kern::Printf("BusError..")); + // clear CSIE bit..and disable HW interrupts.. + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, KHtCSIModeEnable | KSlaveInterruptFlags, 0); + + // clear internal flags + intState = __SPIN_LOCK_IRQSAVE(CsiSpinLock); + iTrigger = 0; + __SPIN_UNLOCK_IRQRESTORE(CsiSpinLock, intState); + } + + // set the callback's trigger.. + aCb->SetTrigger(aTrigger | aCb->GetTrigger()); + } + +// Initializes the hardware with the data provided in the transaction and slave-address field +TInt DCsiChannelSlave::ConfigureInterface() + { + __KTRACE_OPT(KIIC, Kern::Printf("ConfigureInterface()")); + + HCR::TSettingId settingId; + TConfigSpiBufV01* aBuf = (TConfigSpiBufV01*) iConfigHeader; + TConfigSpiV01 &spiHeader = (*aBuf)(); + + // CSI initialization procedure: + // 1. clear CISE bit.. + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, KHtCSIModeEnable, 0); + + // 2. wait until CIS_MODE.bit0 (CSOT) changes to 0 + // start the GuardTimer before while-loop.. + iTransactionStatus = KErrNone; + + iHwGuardTimer.OneShot(NKern::TimerTicks(iHwTimeoutValue)); + + while((iTransactionStatus == KErrNone) && + AsspRegister::Read32(iChannelBase + KHoCSIModeControl) & KHtCSIModeTransferState); + + // check if the the guard timer or transaction timer hasn't expired.. + if(iTransactionStatus != KErrNone) + { + return KErrGeneral; + } + else + { + iHwGuardTimer.Cancel(); + } + + // 3. set CSIRST bit.. + AsspRegister::Modify32(iChannelBase + KHoCSIControl, 0, KHtCSIControlCSIRst); + + // 4. set KHoCSIClockSelect register.. + TUint32 val = 0; + + // CKP - ClocK Polarity (bit 4) 0: initial value is high, 1: initial val is low + // DAP - Clock phase select (bit 3) 0: 180 degree delay, 1: 0 degree delay + // @** don't use DAP=1 when iClock set to KHCSIClockValPCLKdiv4 (HW bug..see SoC errata) + switch (spiHeader.iClkMode) + { + case ESpiPolarityLowRisingEdge: // Active high, odd edges + val = KHtCSIClockSelectCKP; // CKP 1, DAP 0 + break; + case ESpiPolarityLowFallingEdge: // Active high, even edges + val = KHtCSIClockSelectCKP | // CKP 1, DAP 1 + KHtCSIClockSelectDAP; + break; + + case ESpiPolarityHighFallingEdge: // Active low, odd edges + val = 0; // CKP 0, DAP 0 + break; + + case ESpiPolarityHighRisingEdge: // Active low, even edges + val = KHtCSIClockSelectDAP; // CKP 0, DAP 1 + break; + default: + break; // there's no default..no other value can be specified as it's an enum ;) + } + + // we are a Slave - so we use only one setting for the clk speed, ignoring the header + val |= KHCSIClockValSlave; + + // Set the SS pin configuration.. + val |= KHtCSIClockSelectSSE; // SS pin enable + + if (spiHeader.iSSPinActiveMode == ESpiCSPinActiveHigh) + { + val |= KHtCSIClockSelectSSPol; // 1: SS pin high active + } + + // store iSSPinActiveMode internaly - it will be used in interrupts. + iSSPinActiveMode = spiHeader.iSSPinActiveMode; + + // set transaction wait time.. + val |= (0xf & spiHeader.iTransactionWaitCycles) << KHsCSIModeTWait; + + // and finally update the register + AsspRegister::Write32(iChannelBase + KHoCSIClockSelect, val); + + // 5. clear KHtCSIControlCSIRst bit.. + AsspRegister::Modify32(iChannelBase + KHoCSIControl, KHtCSIControlCSIRst, 0); + + // 6. Set Mode Control register: + // Transmission and reception mode + val = KHtCSIModeTrEnable; + + // Select transmit data length (8/16 bits) + if (spiHeader.iWordWidth == ESpiWordWidth_16) + { + iWordSize = 2; + val |= KHtCSIModeDataLen; + } + else + { + iWordSize = 1; + } + + // Select Transfer direction (if set-LSB first) + if (spiHeader.iBitOrder == ELsbFirst) + { + val |= KHtCSIModeTransferDir; + } + + // update the register + AsspRegister::Write32(iChannelBase + KHoCSIModeControl, val); + + // 7. Set FIFO trigger levels + TUint8 csiFifoRxTrigerLvl; // set RxTrigger level + + settingId.iCat = KHcrCat_HWServ_CSI; + settingId.iKey = KHcrKey_CSI_FifoRxTrigerLvl; + TInt r = HCR::GetUInt(settingId, csiFifoRxTrigerLvl); + if(r != KErrNone) + { + __KTRACE_OPT(KIIC, Kern::Printf("Failed to read HCR setting for category = %d and key = %d\n", settingId.iCat, settingId.iKey)); + return r; + } + AsspRegister::Write32(iChannelBase + KHoCSIFifoTrgLvl, + (csiFifoRxTrigerLvl << KHsCSIRxFifoTrgLvl)); + + // 8. Clear all interrupts + AsspRegister::Write32(iChannelBase + KHoCSIIntStatus, KInterruptsAll); + + // 9. Set RxTrig permission and enable TEnd and RxTrg interrupts + AsspRegister::Write32(iChannelBase + KHoCSIControl, KSlaveInterruptFlags); + + // the timeout period to wait for a response from the client. + SetClientWaitTime(KClientWaitTime); + // if the KIIC debug trace flag is set, we need to increase the transaction timeout, + // so that debug traces don't cause timer expiration. This call will overwrite + // previously set value (SetClientWaitTime) and default value set by the PIL (SetMasterWaitTime) + __KTRACE_OPT(KIIC, SetClientWaitTime(KMaxWaitTime)); + __KTRACE_OPT(KIIC, SetMasterWaitTime(KMaxWaitTime)); + + + settingId.iCat = KHcrCat_MHA_Interrupt; + settingId.iKey = iChannelNumber == 0 ? KHcrKey_Interrupt_CSI0 : KHcrKey_Interrupt_CSI1; + + TInt32 interruptId; + r = HCR::GetInt(settingId, interruptId); + if(r != KErrNone) + { + __KTRACE_OPT(KIIC, Kern::Printf("Failed to read HCR setting for category = %d and key = %d\n", settingId.iCat, settingId.iKey)); + return r; + } + + // Bind the ISR for the Slave + iInterruptId = Interrupt::Bind(interruptId, DCsiChannelSlave::CsiIsr, this); + + // this returns interruptId or error code(err < 0) + if (iInterruptId < KErrNone) + { + __KTRACE_OPT(KIIC, Kern::Printf("ERROR: InterruptBind error.. %d", r)); + Kern::Printf("ERROR: InterruptBind error.. %d", r); + r = iInterruptId; + } + + return r; + } + +// This method starts data transfer - filling the Transmit FIFO and enabling the device (CSIE bit) +TInt DCsiChannelSlave::InitTransfer() + { + __KTRACE_OPT(KIIC, Kern::Printf("DCsiChannelSlave::InitTransfer()")); + //__KTRACE_OPT(KIIC, Kern::Printf("Receiving %d, Transmitting %d", (iTrigger & EReceive)>>4, (iTrigger & ETransmit)>>3)); + + TUint r = KErrNone; + TInt intState; + TInt trigger; + + intState = __SPIN_LOCK_IRQSAVE(CsiSpinLock); + if(!iInProgress) + { + // clean the FIFOs.. + AsspRegister::Write32(iChannelBase + KHoCSIOFifoL, 0); + AsspRegister::Write32(iChannelBase + KHoCSIOFifoL, 0); + + // clear CISE bit..re-enable all HW interrupts.. + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, KHtCSIModeEnable, KSlaveInterruptFlags); + + // Clear all interrupts + AsspRegister::Write32(iChannelBase + KHoCSIIntStatus, KInterruptsAll); + } + __SPIN_UNLOCK_IRQRESTORE(CsiSpinLock, intState); + + + intState = __SPIN_LOCK_IRQSAVE(CsiSpinLock); + trigger = iTrigger; + __SPIN_UNLOCK_IRQRESTORE(CsiSpinLock, intState); + + // if we are transmitting - Add data to the FIFO.. + if(trigger & ETransmit) + { + // Set mode to transmission and reception (Set TRMD) + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, 0, KHtCSIModeTrEnable); + + // enable TEND interrupt (e.g. if this is called during the transmission as the result of + // TxUnderrun event. + AsspRegister::Modify32(iChannelBase + KHoCSIControl, 0, KHtCSIControlTEndIE); + + iWordSize = iTxGranularity >> 3; + iTxData = iTxBuf + (iWordSize * iTxOffset); + iTxDataEnd = iTxData + (iWordSize * iNumTxWords); + + __KTRACE_OPT(KIIC, Kern::Printf("Tx Buf: %x", iTxData)); + __KTRACE_OPT(KIIC, Kern::Printf("Tx BufeND: %x", iTxDataEnd)); + + // copy data to the FIFO.. + while(AsspRegister::Read32(iChannelBase + KHoCSIOFifoL) <= (KHwCSIFifoLMax - iWordSize) && // until FIFO not full.. + iTxData != iTxDataEnd) // or whole data has been copied. + { + TUint16 val; + + // in 16bit mode we need to read MSB first.. + if(iWordSize > 1) + { + val = (*iTxData) << 8; // MSB shifted up.. + val |= *(iTxData + 1) & 0xff; // LSB.. + } + else + { + val = *iTxData; + } + + // write this value to the FIFO window register.. + AsspRegister::Write32(iChannelBase + KHoCSIOFifo, val); + + // increment the pointer. + iTxData += iWordSize; + } + + __KTRACE_OPT(KIIC, Kern::Printf("After adding:\n\rTx Buf: %x", iTxData)); + __KTRACE_OPT(KIIC, Kern::Printf("Tx BufeND: %x", iTxDataEnd)); + } + + if(trigger & EReceive) // we are starting receive transfer only.. + { + if(!(trigger & ETransmit)) + { + // if only receiving - set it to reveive-only + // Set mode to reception only (clear TRMD) + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, KHtCSIModeTrEnable, 0); + } + + // enable RxTrg interrupt (e.g. if this is called during the transmission as the result + // of RxOverrun event. + AsspRegister::Modify32(iChannelBase + KHoCSIControl, 0, KHtCSIControlRxTrgIE); + + iWordSize = iRxGranularity >> 3; + iRxData = iRxBuf + (iWordSize * iRxOffset); + iRxDataEnd = iRxData + (iWordSize * iNumRxWords); + + __KTRACE_OPT(KIIC, Kern::Printf("Rx Buffer: %x", iRxData)); + __KTRACE_OPT(KIIC, Kern::Printf("Rx BufreND: %x", iRxDataEnd)); + } + + // enable interrupts.. + Interrupt::Enable(iInterruptId); + + // enable transmission..this will trigger the HW to start the transmission.. + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, 0, KHtCSIModeEnable); + + return r; + } + +// aOperation is a bit-mask made of TPslOperation +TInt DCsiChannelSlave::DoRequest(TInt aOperation) + { +// __KTRACE_OPT(KIIC, Kern::Printf("\n===>DCsiChannelSlave::DoRequest, Operation %x", aOperation)); + + TInt r = KErrNone; + TInt intState; + + if (aOperation & EAsyncConfigPwrUp) + { + __KTRACE_OPT(KIIC, Kern::Printf("EAsyncConfigPwrUp")); + // this is called when the client calls IicBus::CaptureChannel() asynchronously + r = ConfigureInterface(); + ChanCaptureCallback(r); + return r; + } + + // PowerUp + if (aOperation & ESyncConfigPwrUp) + { + __KTRACE_OPT(KIIC, Kern::Printf("ESyncConfigPwrUp")); + // this is called when the client calls IicBus::CaptureChannel() + // - configure the channel with the configuration provided in the header. + r = ConfigureInterface(); + // we can't continue in this case.. + if (r != KErrNone) + { + __KTRACE_OPT(KIIC, Kern::Printf("Coudln't configure the interface..r %d", r)); + return r; + } + } + + if (aOperation & ETransmit) + { + __KTRACE_OPT(KIIC, Kern::Printf("ETransmit")); + intState = __SPIN_LOCK_IRQSAVE(CsiSpinLock); + iTrigger |= ETransmit; + __SPIN_UNLOCK_IRQRESTORE(CsiSpinLock, intState); + } + + if (aOperation & EReceive) + { + __KTRACE_OPT(KIIC, Kern::Printf("EReceive")); + intState = __SPIN_LOCK_IRQSAVE(CsiSpinLock); + iTrigger |= EReceive; + __SPIN_UNLOCK_IRQRESTORE(CsiSpinLock, intState); + } + + if (aOperation & (EReceive | ETransmit)) + { + r = InitTransfer(); + } + + if (aOperation & EAbort) + { + __KTRACE_OPT(KIIC, Kern::Printf("EAbort")); + intState = __SPIN_LOCK_IRQSAVE(CsiSpinLock); + // disable CSI (clear CSIE bit), and interrupts + if(!iInProgress) + { + AsspRegister::Modify32(iChannelBase + KHoCSIModeControl, KHtCSIModeEnable | KSlaveInterruptFlags, 0); + iInProgress = EFalse; + iTrigger = 0; + } + __SPIN_UNLOCK_IRQRESTORE(CsiSpinLock, intState); + Interrupt::Disable(iInterruptId); + } + + if (aOperation & EPowerDown) + { + __KTRACE_OPT(KIIC, Kern::Printf("EPowerDown")); + + // set CSI Rst bit + AsspRegister::Write32(iChannelBase + KHoCSIModeControl, KHtCSIControlCSIRst); + + // disable and unbind the ISR, + Interrupt::Disable(iInterruptId); + Interrupt::Unbind(iInterruptId); + } + return r; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/csi/csi_slave.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/csi/csi_slave.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,98 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#ifndef __CSI_SLAVE_H__ +#define __CSI_SLAVE_H__ + +#include +#include +#include +#ifdef MASTER_MODE +#include "csi_master.h" +#endif +class DCsiChannelSlave: public DIicBusChannelSlave + { + +public: +#ifdef STANDALONE_CHANNEL + IMPORT_C +#endif + static DCsiChannelSlave* New(TInt aChannelNumber, const TBusType aBusType, + const TChannelDuplex aChanDuplex); + // Gateway function for PSL implementation + virtual TInt DoRequest(TInt aOperation); + + DCsiChannelSlave(TInt aChannelNumber, const TBusType aBusType, + const TChannelDuplex aChanDuplex); + +protected: + // overriders for base pure-virtual methods.. + virtual TInt DoCreate(); // second-stage construction, + virtual TInt CheckHdr(TDes8* aHdrBuff); + virtual void ProcessData(TInt aTrigger, TIicBusSlaveCallback* aCb); + +private: + // some internal methods.. + TBool TransConfigDiffersFromPrev(); + TInt ConfigureInterface(); + TInt InitTransfer(); + + // ISR handler and other static methods.. + static void CsiIsr(TAny* aPtr); + static void TimeoutCallback(TAny* aPtr); + static inline void NotifyClientEnd(DCsiChannelSlave* aPtr); + + // as implementation is common/generic for both channels + // store base register address and interruptID + TUint iChannelBase; + TInt iInterruptId; + + // to store SS pin active mode (1-active on high, 0 - active on low) + TInt8 iSSPinActiveMode; + TUint8 iTrigger; + + // granularity.. + TInt8 iWordSize; + + // flags indicating transmission/operation competition + TInt8 iInProgress; + + // pointers to buffers used to transfer data from/to... + TInt8 *iTxData; + TInt8 *iRxData; + TInt8 *iTxDataEnd; + TInt8 *iRxDataEnd; + + // Timer to guard 'while' loops.. + NTimer iHwGuardTimer; + // guard-timer timeout value (in ms) + TInt32 iHwTimeoutValue; + + // status of the transaction + volatile TInt iTransactionStatus; + +#ifdef MASTER_MODE +public: + DCsiChannelMaster *iMasterAddress; +#endif + }; + + + +#endif /*__CSI_SLAVE_H__*/ diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/csi/hcr_psl_config_csi.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/csi/hcr_psl_config_csi.inl Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file is part of the NE1_TB Variant Base Port +* Hardware Configuration Respoitory compiled repository in-line cpp. +* +*/ + + +/** +@file hcr_psl_config_csi.inl +File provides setting definitions for the CSI setting values applicable to the +NEC NaviEngine base port. + +@internalTechnology +*/ + + +#ifndef HCR_PSL_CONFIG_CSI_INL +#define HCR_PSL_CONFIG_CSI_INL + + +// SSettingC gSettingsList[] = +// { +// + + +/** +HCR Settings values for CSI driver service config. + +*/ + { { { KHcrCat_HWServ_CSI, KHcrKey_CSI_NumOfChannels}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(2)}}}, + { { { KHcrCat_HWServ_CSI, KHcrKey_CSI_Timeout}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(20)}}}, + { { { KHcrCat_HWServ_CSI, KHcrKey_CSI_FifoRxTrigerLvl}, ETypeUInt8, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(0)}}}, + { { { KHcrCat_HWServ_CSI, KHcrKey_CSI_FifoTxTrigerLvl}, ETypeUInt8, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(4)}}} + + +// +// Last entry must not end in a ',' as it is present in the enclosing file. +// }; + + +#endif // HCR_PSL_CONFIG_CSI_INL + + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/csi/hcr_psl_config_csi_inc.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/csi/hcr_psl_config_csi_inc.inl Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file is part of the NE1_TB Variant Base Port +* Hardware Configuration Respoitory compiled repository in-line cpp. +* +*/ + + +/** +@file hcr_psl_config_csi_inc.inl +File includes the headers needed to compile the CSI settings and their values +as held in the other INL file: hcr_psl_config_csi.inl. These three files must c +ompile cleanlyin the main hcr_psl_config.cpp file which includes them. + +@internalTechnology +*/ + + +#ifndef HCR_PSL_CONFIG_CSI_INC_INL +#define HCR_PSL_CONFIG_CSI_INC_INL + + +// Assumes HCR mmp has the systeminclude paths for this include to work +// from the variant.mmh +#include + + +#endif // HCR_PSL_CONFIG_CSI_INC_INL + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/csi/hcrconfig_csi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/csi/hcrconfig_csi.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file is part of the NE1_TB Variant Base Port +* Hardware Configuration Respoitory Setting IDs header. +* +*/ + + + +/** +@file hcrconfig_csi.h +File provides definitions for the CSI set of HCR settings +identifiers applicable to the NEC NaviEngine base port. + +@internalTechnology +@prototype +*/ + +#ifndef HCRCONFIG_CSI_H +#define HCRCONFIG_CSI_H + + + +// -- INCLUDES ---------------------------------------------------------------- + +#include + + + +// -- CATEGORY UIDs ----------------------------------------------------------- + + + +// -- KEYS -------------------------------------------------------------------- + +/** +HCR Setting for CSI Service configuration +*/ +#define CSI_BASE 0x00010000 +const HCR::TElementId KHcrKey_CSI_NumOfChannels = CSI_BASE; //< +const HCR::TElementId KHcrKey_CSI_Timeout = CSI_BASE + 1; //< +const HCR::TElementId KHcrKey_CSI_FifoRxTrigerLvl = CSI_BASE + 2; //< +const HCR::TElementId KHcrKey_CSI_FifoTxTrigerLvl = CSI_BASE + 3; //< + +#undef CSI_BASE + +#endif //HCRCONFIG_CSI_H diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/dma.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/dma.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp/dma.mmp +* +*/ + + + +#include +#include "kernel/kern_ext.mmh" + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + +target VariantTarget(dma,dll) +targettype kext +linkas dma.dll +noexportlibrary + +sourcepath ../../../../os/kernelhwsrv/kernel/eka/drivers/dma +source dmapil.cpp + +sourcepath . +source dmapsl.cpp + +library VariantTarget(kanaviengine,lib) + +deffile ../../../../os/kernelhwsrv/kernel/eka/~/dma.def + +epocallowdlldata + +capability all + +VENDORID 0x70000001 + +// Comment out the following macro to run dma driver in single buffered mode +//macro NE1_DMA_DOUBLE_BUFFER + +// This macro prevents the PIL from trying to recover from a missed +// IRQ +// If enabled, the PSL must ensure that no IRQs are missed +macro DISABLE_MISSED_IRQ_RECOVERY + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/dma_v2.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/dma_v2.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp/dma.mmp +* +*/ + + + +#include +#include "kernel/kern_ext.mmh" + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + +target VariantTarget(dma_v2,dll) +targettype kext +linkas dma.dll +noexportlibrary + +sourcepath ../../../../os/kernelhwsrv/kernel/eka/drivers/dma +source dma2_pil.cpp dma2_shared.cpp + +sourcepath . +source dmapsl_v2.cpp + +library VariantTarget(kanaviengine,lib) + +deffile ../../../../os/kernelhwsrv/kernel/eka/~/dma2.def + +epocallowdlldata + +capability all + +VENDORID 0x70000001 + +// Comment out the following macro to run dma driver in single buffered mode +macro NE1_DMA_DOUBLE_BUFFER + +SMPSAFE + +MACRO DMA_APIV2 diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/dmapsl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/dmapsl.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,1084 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\dmapsl.cpp +* DMA Platform Specific Layer (PSL) for Navi Engine. +* +*/ + + + + +#include +#include +#include +#include +#include + +// Debug support +static const char KDmaPanicCat[] = "DMA PSL"; +static const TInt KDesCount = 1024; // DMA descriptor count - sufficient to serve all channels at the time. + +/* Maps logical DMA channels into physical ones */ +static const TDMAChannelLocator KDMAChannelLocator[EDmaChannelCount]= + { + // controller, group, subchannel DCHS (exc. SEL) TransferShiftSize + {EDMACtrl32 ,2 ,2 ,KHvDMACHC_SDR, 1}, //EDMAChannelSD0, + {EDMACtrl32 ,2 ,3 ,KHvDMACHC_SDW, 1}, //EDMAChannelSD1, + + {EDMACtrl32 ,3 ,0 ,KHvDMACHC_I2SR, 1}, //EDMAChannelI2S0RX, + {EDMACtrl32 ,3 ,1 ,KHvDMACHC_I2SW, 1}, //EDMAChannelI2S0TX, + {EDMACtrl32 ,3 ,2 ,KHvDMACHC_I2SR, 1}, //EDMAChannelI2S1RX, + {EDMACtrl32 ,3 ,3 ,KHvDMACHC_I2SW, 1}, //EDMAChannelI2S1TX, + {EDMACtrl32 ,3 ,4 ,KHvDMACHC_I2SR, 1}, //EDMAChannelI2S2RX, + {EDMACtrl32 ,3 ,5 ,KHvDMACHC_I2SW, 1}, //EDMAChannelI2S2TX, + {EDMACtrl32 ,3 ,6 ,KHvDMACHC_I2SR, 1}, //EDMAChannelI2S3RX, + {EDMACtrl32 ,3 ,7 ,KHvDMACHC_I2SW, 1}, //EDMAChannelI2S3TX, + + {EDMACtrl32 ,0 ,2 ,KHvDMACHC_SW, 2}, //EDMAChannelUART0RX, + {EDMACtrl32 ,0 ,3 ,KHvDMACHC_SW, 2}, //EDMAChannelUART0TX, + {EDMACtrl32 ,0 ,4 ,KHvDMACHC_SW, 2}, //EDMAChannelUART1RX, + {EDMACtrl32 ,0 ,5 ,KHvDMACHC_SW, 2}, //EDMAChannelUART1TX, + {EDMACtrl32 ,0 ,6 ,KHvDMACHC_SW, 2}, //EDMAChannelUART2RX, + {EDMACtrl32 ,0 ,7 ,KHvDMACHC_SW, 2}, //EDMAChannelUART2TX, + + {EDMACtrl32 ,0 ,0 ,KHvDMACHC_SW, 2}, //EDmaMemToMem0, + {EDMACtrl32 ,0 ,1 ,KHvDMACHC_SW, 2}, //EDmaMemToMem1, + {EDMACtrl32 ,2 ,4 ,KHvDMACHC_SW, 2}, //EDmaMemToMem2, + {EDMACtrl32 ,2 ,5 ,KHvDMACHC_SW, 2}, //EDmaMemToMem3, + }; + +/* Maps physical EDMACtrl32 channels into logical ones */ +static const int DMAC32_HWChannelsLocator[KDmaHWCtrl32Count][KDmaCtrl32HWSubChannelCount] = + { + {EDmaMemToMem0,EDmaMemToMem1,EDMAChannelUART0RX,EDMAChannelUART0TX, + EDMAChannelUART1RX,EDMAChannelUART1TX,EDMAChannelUART2RX,EDMAChannelUART2TX}, + {-1,-1,-1,-1,-1,-1,-1,-1}, + {-1,-1,EDMAChannelSD0,EDMAChannelSD1,EDmaMemToMem2,EDmaMemToMem3,-1,-1}, + { EDMAChannelI2S0RX,EDMAChannelI2S0TX,EDMAChannelI2S1RX,EDMAChannelI2S1TX, + EDMAChannelI2S2RX,EDMAChannelI2S2TX,EDMAChannelI2S3RX,EDMAChannelI2S3TX}, + {-1,-1,-1,-1,-1,-1,-1,-1}, + }; + +class TDmaDesc +// +// Hardware DMA descriptor +// + { +public: + TPhysAddr iSrcAddr; + TPhysAddr iDestAddr; + TInt iCount; //Transfer counter in bytes + }; + + +// +// Test Support +// +//The list of S/W channels to be tested by t_dma +TUint32 TestNEChannels[] = { EDmaMemToMem0, EDmaMemToMem1, EDmaMemToMem2, EDmaMemToMem3}; +TDmaTestInfo TestInfo = + { + 4*KMaxDMAUnitTransferLen, //a word is a unit of transfer for mem-to-mem DMA + 3, // Word alignement applies fow S/W (mem-to-mem) transfer + 0, // No need for cookie. + 4, // The number of S/W DMA channels to test + TestNEChannels, + 0, + NULL, + 0, + NULL + }; + +EXPORT_C const TDmaTestInfo& DmaTestInfo() + { + return TestInfo; + } + +// +// Helper Functions +// + +inline TBool IsHwDesAligned(TAny* aDes) +// +// We do no need H/W descriptors to be aligned as Navi Engine DMA32 cotroller doesn't +// support linked descriptors. Instead, they are linked by S/W. Therefore, the ordinary +// word alignement applies (which is enforced by compiler). +// + { + return ((TLinAddr)aDes & 0x3) == 0; + } + +// Channel class. +// For double buffering, we cannot use the provided TDmaDbChannel class because +// NE DMA has two sets of registers (base & work) - wich is not supported by TDmaDbChannel. +#if defined(NE1_DMA_DOUBLE_BUFFER) +class TNE1DmaChannel : public TDmaChannel +#else +class TNE1DmaChannel : public TDmaSbChannel +#endif + { +public: + TNE1DmaChannel(); + void ProcessIrq(); + void ProcessErrorIrq(); + void StopTransfer(); + void Close(); + inline TBool IsIdle() const; + +private: +#if defined(NE1_DMA_DOUBLE_BUFFER) + virtual void DoQueue(DDmaRequest& aReq); + virtual void DoCancelAll(); + virtual void DoDfc(DDmaRequest& aCurReq, SDmaDesHdr*& aCompletedHdr); +private: + enum { EIdle = 0, ETransferring, ETransferringLast } iState; +#endif + virtual void QueuedRequestCountChanged(); + + inline void ProcessTC(TBool aClearStatus); + inline void ProcessEnd(TBool aClearStatus); + inline void ClearStatus(TUint32 aBitmask); + inline void HandleIsr(TBool aIsComplete); + +public: + TInt iHWCtrlBase;// Base address of H/W registers for this channel. + TInt iSubChannel;// Subchannel number (0-7) within H/W controller. + TInt iDMACHCReg; // The content of configuration (CHC) register for this channel. + TInt iTransferDataShift;//log2 of basic unit of transfer. See TDMAChannelLocator::iTransferShiftSize + + // The following members are public so that they can be + // modified by the TNaviEngineDmac class + + /** + This flag is set when the base register set is filled + + It allows the ISR to detect the case where a base to work + register set changeover has happened (END interrupt) but has been masked by + the completion of the work register set + */ + TBool iBaseValidSet; + + /** + This counter is incremented each time a LaunchTransfer is started + and decremented when the ISR handles the transfer complete (TC + bit). Ie. it does not keep count of the number of times the base + register set is filled. This allows missed TC interrupts to be + detected. + */ + TInt iTcIrqCount; + + /** + This spinlock is used to protect both the iBaseValidSet and iTcIrqCount + variables. It synchronises access between threads and the ISR. + + For the ISR the setting of iBaseValidSet must appear to be atomic with + the launch of the transfer. + + For iTcIrqCount The spinlock makes the transfer launch and subsequent + increase of the count appear atomic to the ISR. Otherwise it could + observe a completed transfer before the count was incremented or + vice-versa + */ + TSpinLock iIsrLock; + }; + +// +// Derived Controller Class +// +class TNaviEngineDmac : public TDmac + { +public: + TNaviEngineDmac(); + TInt Create(); + + friend void TNE1DmaChannel::HandleIsr(TBool); // Allow channel HandleIsr to call TDmac::HandleIsr +private: + // from TDmac (PIL pure virtual) + virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr); + virtual void StopTransfer(const TDmaChannel& aChannel); + virtual TBool IsIdle(const TDmaChannel& aChannel); + virtual TInt MaxTransferSize(TDmaChannel& aChannel, TUint aFlags, TUint32 aPslInfo); + virtual TUint MemAlignMask(TDmaChannel& aChannel, TUint aFlags, TUint32 aPslInfo); + // from TDmac (PIL virtual) + virtual void InitHwDes(const SDmaDesHdr& aHdr, TUint32 aSrc, TUint32 aDest, TInt aCount, + TUint aFlags, TUint32 aPslInfo, TUint32 aCookie); + virtual void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr); + virtual void AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr, + const SDmaDesHdr& aNewHdr); + virtual void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr); + // other + static void DMAC32_Isr(TAny* aThis, TInt aController, TInt aTcsMask, TInt aCompleted); + static void DMAC32_0_End_Isr(TAny* aThis); + static void DMAC32_0_Err_Isr(TAny* aThis); + static void DMAC32_2_End_Isr(TAny* aThis); + static void DMAC32_2_Err_Isr(TAny* aThis); + static void DMAC32_3_End_Isr(TAny* aThis); + static void DMAC32_3_Err_Isr(TAny* aThis); + static void InitHWChannel (ENaviEngineDmaController aNEController, TInt aGroup, TInt aSubChannel); + static void InitAllHWChannels (); + inline TDmaDesc* HdrToHwDes(const SDmaDesHdr& aHdr); +private: + static const SCreateInfo KInfo; +public: + + void PopulateWorkSet(TNE1DmaChannel& aChannel, const SDmaDesHdr& aHdr); + void LaunchTransfer(TNE1DmaChannel& aChannel, TBool aBaseSetValid); +#if defined(NE1_DMA_DOUBLE_BUFFER) + void PopulateBaseSet(TNE1DmaChannel& aChannel, const SDmaDesHdr& aHdr); + void ContinueTransfer(TNE1DmaChannel& aChannel, TBool aBaseSetValid); +#endif + + TNE1DmaChannel iChannels[EDmaChannelCount]; + }; + +static TNaviEngineDmac Controller; + +const TDmac::SCreateInfo TNaviEngineDmac::KInfo = + { + EDmaChannelCount, + KDesCount, + TDmac::KCapsBitHwDes, + sizeof(TDmaDesc), + EMapAttrSupRw | EMapAttrFullyBlocking //?? + }; + +TNaviEngineDmac::TNaviEngineDmac() +// +// Constructor. +// + : TDmac(KInfo) + {} + +TInt TNaviEngineDmac::Create() +// +// Second phase construction. +// + { + TInt r = TDmac::Create(KInfo); // Base class Create() + if (r == KErrNone) + { + __DMA_ASSERTA(ReserveSetOfDes(EDmaChannelCount) == KErrNone); + + //Read KDMAChannelLocator constants and populate the values in channel objects. + + for (TInt i=0; i < EDmaChannelCount; ++i) + { + TUint ctrlBase = 0; + switch (KDMAChannelLocator[i].iDMACtrl) + { + case EDmaCtrlExBus: ctrlBase = KDMACExBusBase; break; + case EDMACtrl32: ctrlBase = KDMAC32Base; break; + default: __DMA_CANT_HAPPEN(); + } + iChannels[i].iHWCtrlBase = ctrlBase + KDMAChannelLocator[i].iGroup * KDMAGroupOffset + + KDMAChannelLocator[i].iSubChannel * KDMAChannelOffset; + iChannels[i].iSubChannel = KDMAChannelLocator[i].iSubChannel; + iChannels[i].iDMACHCReg = KDMAChannelLocator[i].iDMACHCReg | iChannels[i].iSubChannel; + iChannels[i].iTransferDataShift = KDMAChannelLocator[i].iTransferShiftSize; + iFreeHdr = iFreeHdr->iNext; + } + + //Bind DMA interrupt for channels we support + TInt irqh0 = Interrupt::Bind(KIntDMAC32_0_End, DMAC32_0_End_Isr, this); __DMA_ASSERTA(irqh0>=0); + TInt irqh1 = Interrupt::Bind(KIntDMAC32_0_Err, DMAC32_0_Err_Isr, this); __DMA_ASSERTA(irqh1>=0); + TInt irqh2 = Interrupt::Bind(KIntDMAC32_2_End, DMAC32_2_End_Isr, this); __DMA_ASSERTA(irqh2>=0); + TInt irqh3 = Interrupt::Bind(KIntDMAC32_2_Err, DMAC32_2_Err_Isr, this); __DMA_ASSERTA(irqh3>=0); + TInt irqh4 = Interrupt::Bind(KIntDMAC32_3_End, DMAC32_3_End_Isr, this); __DMA_ASSERTA(irqh4>=0); + TInt irqh5 = Interrupt::Bind(KIntDMAC32_3_Err, DMAC32_3_Err_Isr, this); __DMA_ASSERTA(irqh5>=0); + + + if (r == KErrNone) + { + InitAllHWChannels(); + + r = Interrupt::Enable(irqh0); __DMA_ASSERTA(r==KErrNone); + r = Interrupt::Enable(irqh1); __DMA_ASSERTA(r==KErrNone); + r = Interrupt::Enable(irqh2); __DMA_ASSERTA(r==KErrNone); + r = Interrupt::Enable(irqh3); __DMA_ASSERTA(r==KErrNone); + r = Interrupt::Enable(irqh4); __DMA_ASSERTA(r==KErrNone); + r = Interrupt::Enable(irqh5); __DMA_ASSERTA(r==KErrNone); + + } + } + return r; + } + +// Initialises all H/W channels. This will make sure they are off on soft restart. +void TNaviEngineDmac::InitAllHWChannels() + { + int i,j; + for (i=0;i(aChannel); + TNE1DmaChannel& channel = static_cast(mutableChannel); + + const TInt irq = __SPIN_LOCK_IRQSAVE(channel.iIsrLock); + // The fragment descriptor (src/dest address, size) should be placed into either "Work Set" or "Base Set" + // depending on the actual state of the H/W + if (IsIdle(channel)) + { + // The channel is idle, for the (most likely) reason that both "Work Set" and "Base Set" transfers are + // completed since the last time we run this function. + #ifdef _DEBUG + Transfer_IdleOnStart++; + #endif + PopulateWorkSet(channel, aHdr); // Populate "Work Set" + LaunchTransfer(channel, EFalse); // Start the transfer, base set is invalid + } + else + { + // "Work Set" transfer is still going on. It seems we will manage to place + // the next fragment in time for continious traffic flow. + #ifdef _DEBUG + Transfer_NotIdleOnStart++; + #endif + PopulateBaseSet(channel, aHdr); // Populate "Base Set" + ContinueTransfer(channel, ETrue);// Indicate Base Set is valid (bvalid = ETrue) + + // We should expect here that the "work set" traffic is still in progress. + // Once it is completed, "Base Set" content is copied into "Work Set" and the traffic will go on. + // However, there is a corner case where we configure "Base Set" too late. + // Therefore, check if transfer is still active. + if (IsIdle(channel)) + { + // There is no DMA traffic. There could be two reason for that. Either, + // 1. The transfer we have just configured in "Base Set" has already completed, or + // 2. We configured base set too late, after "Work Set" transfer has already finished. + + // Check BVALID bit + // if its now clear, then it was set in time, if it's + // still set it was set too late + const TUint32 dchs = AsspRegister::Read32(channel.iHWCtrlBase+KHoDMACHS); + const TBool bvalidSet = dchs & KHtDMACHS_BVALID; + + if (!bvalidSet) + { + DMA_PSL_CHAN_TRACE_STATIC(channel, "Base set transferred already"); + #ifdef _DEBUG + Transfer_MatchWorkSetTrue++; + #endif + } + else + { + DMA_PSL_CHAN_TRACE_STATIC(channel, "Too late for base set"); + + // BVALID bit was set after "Work Set" transfer completed, and DMA H/W didn't + // copy the content of "Base Set" into "Work Set". We have to re-launch the transfer. + // This time we have to configure "Work Set" + #ifdef _DEBUG + Transfer_MatchWorkSetFalse++; + #endif + PopulateWorkSet(channel, aHdr); // Populate "Work Set". + LaunchTransfer(channel, EFalse); // Start the transfer, "Base Set" is invalid. + } + } + } + __SPIN_UNLOCK_IRQRESTORE(channel.iIsrLock, irq); + } +#else +void TNaviEngineDmac::Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr) +// +// Initiates a (previously constructed) request on a specific channel. +// + { + TDmaChannel& mutableChannel = const_cast(aChannel); + TNE1DmaChannel& channel = static_cast(mutableChannel); + + DMA_PSL_CHAN_TRACE_STATIC1(channel, ">TNaviEngineDmac::Transfer des=0x%08X", HdrToHwDes(aHdr)); + + const TInt irq = __SPIN_LOCK_IRQSAVE(channel.iIsrLock); + // The fragment descriptor (src/dest address, size) should be placed into either "Work Set" or "Base Set" + // depending on the actual state of the H/W + __NK_ASSERT_ALWAYS(IsIdle(channel)); + PopulateWorkSet(channel, aHdr); // Populate "Work Set" + LaunchTransfer(channel, EFalse); // Start the transfer, base set is invalid + __SPIN_UNLOCK_IRQRESTORE(channel.iIsrLock, irq); + } +#endif + + +void TNaviEngineDmac::StopTransfer(const TDmaChannel& aChannel) +// +// Stops a running channel. +// + { + TDmaChannel& mutableChannel = const_cast(aChannel); + TNE1DmaChannel& channel = static_cast(mutableChannel); + + __KTRACE_OPT(KDMA, Kern::Printf(">TNaviEngineDmac::StopTransfer channel=%d", channel.PslId())); + + channel.StopTransfer(); + + __KTRACE_OPT(KDMA, Kern::Printf("(aChannel); + TNE1DmaChannel& channel = static_cast(mutableChannel); + + const TBool idle = channel.IsIdle(); + __KTRACE_OPT(KDMA, Kern::Printf(">Dmac::IsIdle channel=%d, idle=%d", channel.PslId(), idle)); + return idle; + } + +// Places the descriptor into "Work Set" +void TNaviEngineDmac::PopulateWorkSet(TNE1DmaChannel& aChannel, const SDmaDesHdr& aHdr) + { + TDmaDesc* pD = HdrToHwDes(aHdr); + __KTRACE_OPT(KDMA, Kern::Printf(">TNaviEngineDmac::PopulateWorkSet channel=%d des=0x%08X", aChannel.PslId(), pD)); + + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMACHC, aChannel.iDMACHCReg); //configure channel + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMASAW, pD->iSrcAddr); //source addr + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMADAW, pD->iDestAddr); //dest addr + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMATCW, (pD->iCount>>aChannel.iTransferDataShift)-1); //transfer counter + } + +// Starts the transfer. +// @pre The chanel is idle. +// @arg aBaseSetValid if true, BVALID bit should be set. +// @pre iIsrLock must be held +void TNaviEngineDmac::LaunchTransfer(TNE1DmaChannel& aChannel, TBool aBaseSetValid) + { + __KTRACE_OPT(KDMA, Kern::Printf(">TNaviEngineDmac::LaunchTransfer channel=%d", aChannel.PslId())); + TInt val = KHtDMACHS_EN|KHtDMACHS_EN_EN; + if (TUint(aChannel.iDMACHCReg ^ aChannel.iSubChannel) == (TUint)KHvDMACHC_SW) + val |=KHtDMACHS_STG; + if (aBaseSetValid) + val|=KHtDMACHS_BVALID; + + aChannel.iBaseValidSet = aBaseSetValid; + + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMACHS, val); + + aChannel.iTcIrqCount++; + DMA_PSL_CHAN_TRACE_STATIC1(aChannel, "inc iTcIrqCount to %d", aChannel.iTcIrqCount); + } + +#if defined(NE1_DMA_DOUBLE_BUFFER) +// Places the descriptor into "Base Set" +void TNaviEngineDmac::PopulateBaseSet(TNE1DmaChannel& aChannel, const SDmaDesHdr& aHdr) + { + TDmaDesc* pD = HdrToHwDes(aHdr); + __KTRACE_OPT(KDMA, Kern::Printf(">TNaviEngineDmac::PopulateBaseSet channel=%d des=0x%08X", aChannel.PslId(), pD)); + + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMASAB, pD->iSrcAddr); // Source addr + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMADAB, pD->iDestAddr); // Dest addr + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMATCB, (pD->iCount>>aChannel.iTransferDataShift)-1); // Transfer counter + } + +// @pre DMA transfer is in progress. +// @arg aBaseSetValid if true, BVALID bit should be set. +// @pre iIsrLock must be held +void TNaviEngineDmac::ContinueTransfer(TNE1DmaChannel& aChannel, TBool aBaseSetValid) + { + __KTRACE_OPT(KDMA, Kern::Printf(">TNaviEngineDmac::ContinueTransfer channel=%d", aChannel.PslId())); + TInt val = 0; + if (TUint(aChannel.iDMACHCReg ^ aChannel.iSubChannel) == (TUint)KHvDMACHC_SW) + val |=KHtDMACHS_STG; // Set software trigger + if (aBaseSetValid) + { + __NK_ASSERT_DEBUG(!aChannel.iBaseValidSet); + aChannel.iBaseValidSet = ETrue; + val|=KHtDMACHS_BVALID; + } + + if (val) + { + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMACHS, val); + } + } + +// As in TDmaDbChannel, except for EIdle state as we have place the 1st and the 2nd +// fragment into different registers. +void TNE1DmaChannel::DoQueue(DDmaRequest& aReq) + { + TNaviEngineDmac* controller = (TNaviEngineDmac*)iController; + + switch (iState) + { + case EIdle: + { + controller->PopulateWorkSet(*this, *iCurHdr); + const TInt irq = __SPIN_LOCK_IRQSAVE(iIsrLock); + if (iCurHdr->iNext) + { + controller->PopulateBaseSet(*this, *(iCurHdr->iNext)); + controller->LaunchTransfer(*this, ETrue);//BaseSetValid=True + iState = ETransferring; + } + else + { + controller->LaunchTransfer(*this, EFalse);//BaseSetValid=False + iState = ETransferringLast; + } + __SPIN_UNLOCK_IRQRESTORE(iIsrLock, irq); + break; + } + case ETransferring: + // nothing to do + break; + case ETransferringLast: + iController->Transfer(*this, *(aReq.iFirstHdr)); + iState = ETransferring; + break; + default: + __DMA_CANT_HAPPEN(); + } + } + +//As in TDmaDbChannel +void TNE1DmaChannel::DoCancelAll() + { + iState = EIdle; + } + +// As in TDmaDbChannel +void TNE1DmaChannel::DoDfc(DDmaRequest& /*aCurReq*/, SDmaDesHdr*& aCompletedHdr) + { + aCompletedHdr = iCurHdr; + iCurHdr = iCurHdr->iNext; + switch (iState) + { + case ETransferringLast: + iState = EIdle; + break; + case ETransferring: + if (iCurHdr->iNext == NULL) + iState = ETransferringLast; + else + iController->Transfer(*this, *(iCurHdr->iNext)); + break; + default: + __DMA_CANT_HAPPEN(); + } + } +#endif + +TNE1DmaChannel::TNE1DmaChannel() + :iBaseValidSet(EFalse), iTcIrqCount(0), iIsrLock(TSpinLock::EOrderGenericIrqHigh0) + {} + +/** +Handles normal interrupts as well as recovering from missed interrupts. +It must therefore be called during an ISR, for every valid, open channel +on a DMAC .ie not just channels which have status bits set. +*/ +void TNE1DmaChannel::ProcessIrq() + { + // The spinlock protects access to the iBaseValidSet flag + // This is needed because it is possible for TNaviEngineDmac::Transfer to + // attempt to populate the base set, set iBaseValidSet, but then + // realize it was too late, and have to unset it. + const TInt irq = __SPIN_LOCK_IRQSAVE(iIsrLock); + + // check that channel is open + if(iController == NULL) + { + __SPIN_UNLOCK_IRQRESTORE(iIsrLock, irq); + return; + } + + const TInt irqCount = iTcIrqCount; + __NK_ASSERT_ALWAYS(irqCount >= 0); + __NK_ASSERT_ALWAYS(irqCount < 3); + + TUint32 dchs = AsspRegister::Read32(iHWCtrlBase+KHoDMACHS); + + // Detect if we have missed 1 TC interrupt. + // This can happen when there is one transfer in progress, + // and the channel attempts to populate the base reg set, but + // is too late and launches a new transfer. The second transfer + // may then complete during the ISR of the first, or the ISR may + // not run untill after the second has already completed. + if((irqCount > 0) && IsIdle()) + { + // Reread status now that we have observed channel as idle. + // If a transfer completed between the first read and now, we + // can handle that as a normal interrupt instead of as a + // missed interrupt. This is not essential, just neater + dchs = AsspRegister::Read32(iHWCtrlBase+KHoDMACHS); + if(irqCount == 1) // There may or may not be a missed IRQ + { + if((dchs & KHtDMACHS_TC) == 0) + { + DMA_PSL_CHAN_TRACE1("Channel had missed TC IRQ irqs=%d", irqCount); + ProcessTC(EFalse); + } + } + else if(irqCount == 2) // There is 1 missed and 1 normal IRQ + { + DMA_PSL_CHAN_TRACE1("Channel had missed TC IRQ irqs=%d", irqCount); + ProcessTC(EFalse); + + // Ensure that remaining IRQ will be dealt with in next block + __NK_ASSERT_ALWAYS((dchs & KHtDMACHS_TC)); + } + else + { + // It should not be possible for there to be more than 2 + // outstanding transfers launched + FAULT(); + } + } + + // Deal with normal interrupts + if (dchs&KHtDMACHS_TC) + { + // ISR should not be able to observe the BVALID bit itself + // since TNaviEngineDmac::Transfer should hold iIsrLock whilst + // it decides if it was set in time + __NK_ASSERT_DEBUG(!(dchs & KHtDMACHS_BVALID)); + + // Here we find out if a base-set-copy (END) interrupt has + // been missed. If a TC comes shortly after an END IRQ then + // it would be impossible to tell by looking at the status + // register alone + if(iBaseValidSet) + { + DMA_PSL_CHAN_TRACE("END irq missed "); + ProcessEnd(EFalse); + } + ProcessTC(ETrue); + } + else if (dchs&KHtDMACHS_END) + { + ProcessEnd(ETrue); + } + + __SPIN_UNLOCK_IRQRESTORE(iIsrLock, irq); + } + +void TNE1DmaChannel::ProcessErrorIrq() + { + const TInt irq = __SPIN_LOCK_IRQSAVE(iIsrLock); + + // check that channel is open + if(iController == NULL) + { + __SPIN_UNLOCK_IRQRESTORE(iIsrLock, irq); + return; + } + + // reset channel + ClearStatus(KHtDMACHS_FCLR); + TInt badIrqCount = iTcIrqCount; + iTcIrqCount = 0; + + if(iBaseValidSet) + { + iBaseValidSet = EFalse; + badIrqCount++; + } + + // complete all outstanding requests as being in error + for(TInt i=0; i < badIrqCount; i++) + { + HandleIsr(EFalse); + } + + __SPIN_UNLOCK_IRQRESTORE(iIsrLock, irq); + } +/** +Handle a transfer complete (work set transfer complete and base set was +empty) on this channel. + +@param aClearStatus - Status bits should be cleared +*/ +void TNE1DmaChannel::ProcessTC(TBool aClearStatus) + { + // iTcIrqCount may be zero if StopTransfer were called + // between the transfer being started and the ISR running + if(iTcIrqCount>0) + { + DMA_PSL_CHAN_TRACE1("dec iTcIrqCount to %d", iTcIrqCount); + iTcIrqCount--; + DMA_PSL_CHAN_TRACE("TC"); + HandleIsr(ETrue); + } + + __NK_ASSERT_DEBUG(iTcIrqCount >= 0); + + if(aClearStatus) + ClearStatus(KHtDMACHS_TC|KHtDMACHS_END); //Traffic completed BVALID=OFF + } + +/** +Handle a END (transfer complete, base set loaded in to work set) on this channel. + +@param aClearStatus - Status bit should be cleared +*/ +void TNE1DmaChannel::ProcessEnd(TBool aClearStatus) + { + if(iBaseValidSet) + { + DMA_PSL_CHAN_TRACE("END"); + iBaseValidSet = EFalse; + HandleIsr(ETrue); + } + + if(aClearStatus) + ClearStatus(KHtDMACHS_END); //Traffic completed BVALID=ON + } + +/** +@param aBitmask The bits to be cleared in this channel's status register +*/ +void TNE1DmaChannel::ClearStatus(TUint32 aBitmask) + { + if (TUint((this->iDMACHCReg) ^ (this->iSubChannel)) == (TUint)KHvDMACHC_SW) + aBitmask |= KHtDMACHS_STG; //Add STG for S/W channel + + AsspRegister::Write32(iHWCtrlBase+KHoDMACHS, aBitmask); //End-of-Int + } + +/** +Call HandleIsr for this channel +*/ +void TNE1DmaChannel::HandleIsr(TBool aIsComplete) + { + // iController must be casted so that the private method + // TDmac::HandleIsr can be called since this method is + // a friend of TNaviEngineDmac, but not TDmac. + static_cast(iController)->HandleIsr(*this, aIsComplete); + } + +/** +Stop transfer for this channel +*/ +void TNE1DmaChannel::StopTransfer() + { + const TInt irq = __SPIN_LOCK_IRQSAVE(iIsrLock); + // At this point, device driver should have cancelled DMA request. + + // The procedure for clearing the EN bit to 0 via CPU access during DMA transfer (EN bit = 1) + TUint32 dmaCHS = AsspRegister::Read32(iHWCtrlBase+KHoDMACHS); + + // Read the DCHSn register to be cleared at the relevant channel and confirm that + // both the RQST and ACT bits are cleared to 0. If either or both of them are 1, + // perform polling until their values become 0.. + // OR unless KHtDMACHS_EN is already cleared by the HW at the end of the transfer - + // while we're polling... + while( (dmaCHS & KHtDMACHS_EN) && + dmaCHS & (KHtDMACHS_RQST | KHtDMACHS_ACT) ) + { + dmaCHS = AsspRegister::Read32(iHWCtrlBase+KHoDMACHS); + } + + // enable writing to EN bit.. + dmaCHS |= KHtDMACHS_EN_EN; + AsspRegister::Write32(iHWCtrlBase+KHoDMACHS, dmaCHS); + + // clear the EN bit to 0 + // and set the FCLR bit of the DCHSn register to 1. + dmaCHS &= (~KHtDMACHS_EN); + dmaCHS |= KHtDMACHS_FCLR; + AsspRegister::Write32(iHWCtrlBase+KHoDMACHS, dmaCHS); + + // check that channel is idle, and status bits have been cleared + __NK_ASSERT_ALWAYS(IsIdle()); + dmaCHS = AsspRegister::Read32(iHWCtrlBase+KHoDMACHS); + __NK_ASSERT_ALWAYS((dmaCHS & (KHtDMACHS_TC | KHtDMACHS_END)) == 0); + __NK_ASSERT_ALWAYS(iTcIrqCount >=0); + + // given the above checks, clear the iTcIrqCount and iBaseValidSet so + // that the ISR won't mistakenly think there are missed interrupts + iTcIrqCount = 0; + iBaseValidSet = EFalse; + + __SPIN_UNLOCK_IRQRESTORE(iIsrLock, irq); + } + +/** +@pre Channel has been stopped +*/ +void TNE1DmaChannel::Close() + { + // The lock prevents a channel being closed + // during an ISR. + const TInt irq = __SPIN_LOCK_IRQSAVE(iIsrLock); + DMA_PSL_CHAN_TRACE("Close"); + + // Check that the channel was Idle and Stopped + __NK_ASSERT_ALWAYS(IsIdle()); + __NK_ASSERT_ALWAYS(iTcIrqCount == 0); + __NK_ASSERT_ALWAYS(!iBaseValidSet); + + + // Here we clear iController in advance of the PIL + // If we did not do this, then when we release the lock, the ISR + // could observe it as non-null, proceed, but then have the PIL + // clear it mid-isr + iController = NULL; + + __SPIN_UNLOCK_IRQRESTORE(iIsrLock, irq); + } + +TBool TNE1DmaChannel::IsIdle() const + { + TUint status = AsspRegister::Read32(iHWCtrlBase+KHoDMACHS); + return !(status & KHtDMACHS_EN); + } + + +void TNE1DmaChannel::QueuedRequestCountChanged() + { + const TInt qreqs = __e32_atomic_load_acq32(&iQueuedRequests); + DMA_PSL_CHAN_TRACE1("TNE1DmaChannel::QueuedRequestCountChanged() %d", qreqs); + __DMA_ASSERTA(qreqs >= 0); + } + + +TInt TNaviEngineDmac::MaxTransferSize(TDmaChannel& aChannel, TUint /*aFlags*/, TUint32 /*aPslInfo*/) +// +// Returns the maximum transfer size for a given transfer. +// + { + TNE1DmaChannel& channel = (TNE1DmaChannel&)aChannel; + return (1<iSrcAddr = (aFlags & KDmaPhysAddrSrc) ? aSrc : Epoc::LinearToPhysical(aSrc); + pD->iDestAddr = (aFlags & KDmaPhysAddrDest) ? aDest : Epoc::LinearToPhysical(aDest); + pD->iCount = aCount; + } + +void TNaviEngineDmac::ChainHwDes(const SDmaDesHdr& /*aHdr*/, const SDmaDesHdr& /*aNextHd*/) +// +// Chains hardware descriptors together. +// DMAC32 doesn't support linked descriptors, therefore there is nothing we have to do here. +// + { + } + +void TNaviEngineDmac::AppendHwDes(const TDmaChannel& /*aChannel*/, const SDmaDesHdr& /*aLastHdr*/, + const SDmaDesHdr& /*aNewHdr*/) +// +// Appends a descriptor to the chain while the channel is running. +// DMAC32 doesn't support linked descriptors, therefore there is nothing we have to do here. +// + { + } + +void TNaviEngineDmac::UnlinkHwDes(const TDmaChannel& /*aChannel*/, SDmaDesHdr& /*aHdr*/) +// +// Unlink the last item in the h/w descriptor chain from a subsequent chain that it was possibly linked to. +// DMAC32 doesn't support linked descriptors, therefore there is nothing we have to do here. +// + { + } + + void TNaviEngineDmac::DMAC32_Isr(TAny* aThis, TInt aController, TInt aDmaStat, TInt aCompleted) + // + // Generic part for all DMA32 interrupts. + // Reads the interrupt identification and calls back into the base class + // interrupt service handler with the channel identifier and an indication whether the + // transfer completed correctly or with an error. + // + { + DMA_PSL_TRACE("Begin ISR"); + + TNaviEngineDmac& me = *static_cast(aThis); + int i; + + if (aCompleted) // Transfer-completed interrupt has occured + { + // Go through the all eight subchannels to check which event has occured. + for (i=0;i= EDma32ChannelCount) __DMA_CANT_HAPPEN(); + #endif + + // Skip unused physical channels + // .ie those with no corresponding entry + // in KDMAChannelLocator + if(channel == -1) + continue; + + TNE1DmaChannel& ne1Chan = me.iChannels[channel]; + + ne1Chan.ProcessIrq(); + } + } + else // Error interrupt has occured. aDmaStat is not valid. Should read H/W registers. + { + // Go through the all eight subchannels to check which event has occured. + for (i=0;i= EDmaChannelCount) __DMA_CANT_HAPPEN(); + #endif + TNE1DmaChannel& ne1Chan = me.iChannels[channel]; + ne1Chan.ProcessErrorIrq(); + } + } + } +#if defined(NE1_DMA_DOUBLE_BUFFER) + #ifdef _DEBUG + InterruptCounter_DMA32++; + #endif +#endif + } + + + void TNaviEngineDmac::DMAC32_0_End_Isr(TAny* aThis) + { + TInt stat = (TInt)AsspRegister::Read32(KDMAC32Base+0*KDMAGroupOffset+KHoDMASTAT); + DMAC32_Isr(aThis, 0, stat, 1); + } + void TNaviEngineDmac::DMAC32_2_End_Isr(TAny* aThis) + { + TInt stat = (TInt)AsspRegister::Read32(KDMAC32Base+2*KDMAGroupOffset+KHoDMASTAT); + DMAC32_Isr(aThis, 2, stat, 1); + } + void TNaviEngineDmac::DMAC32_3_End_Isr(TAny* aThis) + { + TInt stat = (TInt)AsspRegister::Read32(KDMAC32Base+3*KDMAGroupOffset+KHoDMASTAT); + DMAC32_Isr(aThis, 3, stat, 1); + } + + void TNaviEngineDmac::DMAC32_0_Err_Isr(TAny* aThis) + { + DMAC32_Isr(aThis, 0, 0, 0); + } +void TNaviEngineDmac::DMAC32_2_Err_Isr(TAny* aThis) + { + DMAC32_Isr(aThis, 2, 0, 0); + } +void TNaviEngineDmac::DMAC32_3_Err_Isr(TAny* aThis) + { + DMAC32_Isr(aThis, 3, 0, 0); + } + +inline TDmaDesc* TNaviEngineDmac::HdrToHwDes(const SDmaDesHdr& aHdr) +// +// Changes return type of base class call. +// + { + return static_cast(TDmac::HdrToHwDes(aHdr)); + } + +// +// Channel Opening/Closing (Channel Allocator) +// + +TDmaChannel* DmaChannelMgr::Open(TUint32 aOpenId) + { + __KTRACE_OPT(KDMA, Kern::Printf(">DmaChannelMgr::Open aOpenId=%d", aOpenId)); + + __DMA_ASSERTA(aOpenId < static_cast(EDmaChannelCount)); + + TDmaChannel* pC = Controller.iChannels + aOpenId; + if (pC->IsOpened()) + pC = NULL; + else + { + pC->iController = &Controller; + pC->iPslId = aOpenId; + } + return pC; + } + +void DmaChannelMgr::Close(TDmaChannel* aChannel) + { + static_cast(aChannel)->Close(); + } + +TInt DmaChannelMgr::StaticExtension(TInt /* aCmd */, TAny* /* aArg */) + { + return KErrNotSupported; + } + +// +// DLL Exported Function +// + +DECLARE_STANDARD_EXTENSION() +// +// Creates and initializes a new DMA controller object on the kernel heap. +// + { + __KTRACE_OPT2(KBOOT, KDMA, Kern::Printf("Starting DMA Extension")); + + return Controller.Create(); + } diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/dmapsl_v2.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/dmapsl_v2.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,2059 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\dmapsl.cpp +* DMA Platform Specific Layer (PSL) for Navi Engine. +* +*/ + + + +#include +#include +#include +#include + +#include +#include + + +// This macro was used to print debug info in the DMAC64 isr. +// It may be useful to reenable it as it appears to provoke an SMP +// race condition, which needs fixing +//#define _DEBUG_PRINT_ISR + +// Debug support +static const char KDmaPanicCat[] = "DMA PSL"; +static const TInt KDesCount = 1024; // DMA descriptor count - sufficient to serve all channels at the time. + +/* Maps logical DMA channels into physical ones */ +static const TDMAChannelLocator KDMAChannelLocator[EDmaChannelCount]= + { + // controller, group, subchannel DCHS (exc. SEL) TransferShiftSize + {EDMACtrl32 ,2 ,2 ,KHvDMACHC_SDR, 1}, //EDMAChannelSD0, + {EDMACtrl32 ,2 ,3 ,KHvDMACHC_SDW, 1}, //EDMAChannelSD1, + + {EDMACtrl32 ,3 ,0 ,KHvDMACHC_I2SR, 1}, //EDMAChannelI2S0RX, + {EDMACtrl32 ,3 ,1 ,KHvDMACHC_I2SW, 1}, //EDMAChannelI2S0TX, + {EDMACtrl32 ,3 ,2 ,KHvDMACHC_I2SR, 1}, //EDMAChannelI2S1RX, + {EDMACtrl32 ,3 ,3 ,KHvDMACHC_I2SW, 1}, //EDMAChannelI2S1TX, + {EDMACtrl32 ,3 ,4 ,KHvDMACHC_I2SR, 1}, //EDMAChannelI2S2RX, + {EDMACtrl32 ,3 ,5 ,KHvDMACHC_I2SW, 1}, //EDMAChannelI2S2TX, + {EDMACtrl32 ,3 ,6 ,KHvDMACHC_I2SR, 1}, //EDMAChannelI2S3RX, + {EDMACtrl32 ,3 ,7 ,KHvDMACHC_I2SW, 1}, //EDMAChannelI2S3TX, + + {EDMACtrl32 ,0 ,2 ,KHvDMACHC_SW, 2}, //EDMAChannelUART0RX, + {EDMACtrl32 ,0 ,3 ,KHvDMACHC_SW, 2}, //EDMAChannelUART0TX, + {EDMACtrl32 ,0 ,4 ,KHvDMACHC_SW, 2}, //EDMAChannelUART1RX, + {EDMACtrl32 ,0 ,5 ,KHvDMACHC_SW, 2}, //EDMAChannelUART1TX, + {EDMACtrl32 ,0 ,6 ,KHvDMACHC_SW, 2}, //EDMAChannelUART2RX, + {EDMACtrl32 ,0 ,7 ,KHvDMACHC_SW, 2}, //EDMAChannelUART2TX, + + {EDMACtrl32 ,0 ,0 ,KHvDMACHC_SW, 2}, //EDmaMemToMem0, + {EDMACtrl32 ,0 ,1 ,KHvDMACHC_SW, 2}, //EDmaMemToMem1, + {EDMACtrl32 ,2 ,4 ,KHvDMACHC_SW, 2}, //EDmaMemToMem2, + {EDMACtrl32 ,2 ,5 ,KHvDMACHC_SW, 2}, //EDmaMemToMem3, + + {EDmaCtrl64 ,NULL ,NULL ,NULL, NULL}, //EDma64MemToMem0, + {EDmaCtrl64 ,NULL ,NULL ,NULL, NULL}, //EDma64MemToMem1, + {EDmaCtrl64 ,NULL ,NULL ,NULL, NULL}, //EDma64MemToMem2, + {EDmaCtrl64 ,NULL ,NULL ,NULL, NULL}, //EDma64MemToMem3, + }; + +/* Maps physical EDMACtrl32 channels into logical ones */ +static const int DMAC32_HWChannelsLocator[KDmaHWCtrl32Count][KDmaCtrl32HWSubChannelCount] = + { + {EDmaMemToMem0,EDmaMemToMem1,EDMAChannelUART0RX,EDMAChannelUART0TX, + EDMAChannelUART1RX,EDMAChannelUART1TX,EDMAChannelUART2RX,EDMAChannelUART2TX}, + {-1,-1,-1,-1,-1,-1,-1,-1}, + {-1,-1,EDMAChannelSD0,EDMAChannelSD1,EDmaMemToMem2,EDmaMemToMem3,-1,-1}, + { EDMAChannelI2S0RX,EDMAChannelI2S0TX,EDMAChannelI2S1RX,EDMAChannelI2S1TX, + EDMAChannelI2S2RX,EDMAChannelI2S2TX,EDMAChannelI2S3RX,EDMAChannelI2S3TX}, + {-1,-1,-1,-1,-1,-1,-1,-1}, + }; + +class TDmaDesc +// +// Hardware DMA descriptor +// + { +public: + TPhysAddr iSrcAddr; + TPhysAddr iDestAddr; + TUint iCount; // Transfer counter in bytes + }; + + +// +// Test Support +// +//The list of S/W channels to be tested by t_dma +TUint32 TestNEChannels[] = { EDmaMemToMem0, EDmaMemToMem1, EDmaMemToMem2, EDmaMemToMem3}; + +//Sg channels on the 64 bit controller +TUint32 TestNESgChannels[] = { EDma64MemToMem0, EDma64MemToMem1, EDma64MemToMem2, EDma64MemToMem3}; +const TInt TestNESgChannelsSize = sizeof(TestNESgChannels)/sizeof(TestNESgChannels[0]); + +/** +Information about the DMA drivers and available +channel cookies for the test harness +*/ +TDmaTestInfo TestInfo = + { + 4 * KMaxDMAUnitTransferLen, //a word is a unit of transfer for mem-to-mem DMA + 3, // Word alignement applies fow S/W (mem-to-mem) transfer + 0, // No need for cookie. + 4, // The number of S/W DMA channels to test + TestNEChannels, + 0, + NULL, + TestNESgChannelsSize, + TestNESgChannels, + }; + +EXPORT_C const TDmaTestInfo& DmaTestInfo() + { + return TestInfo; + } + +/** +Information about the DMA drivers and available +channel cookies for the test harness (V2) +*/ +TDmaV2TestInfo TestInfov2 = + { + 4 * KMaxDMAUnitTransferLen, //a word is a unit of transfer for mem-to-mem DMA + 3, // Word alignement applies fow S/W (mem-to-mem) transfer + 0, // No need for cookie. + 4, // The number of S/W DMA channels to test + {EDmaMemToMem0, EDmaMemToMem1, EDmaMemToMem2, EDmaMemToMem3}, + 0, + {NULL,}, + TestNESgChannelsSize, + {EDma64MemToMem0, EDma64MemToMem1, EDma64MemToMem2, EDma64MemToMem3} + }; + +EXPORT_C const TDmaV2TestInfo& DmaTestInfoV2() + { + return TestInfov2; + } + +// +// Helper Functions +// + +inline TBool IsHwDesAligned(const TAny* aDes) +// +// We do no need H/W descriptors to be aligned as Navi Engine DMA32 cotroller doesn't +// support linked descriptors. Instead, they are linked by S/W. Therefore, the ordinary +// word alignement applies (which is enforced by compiler). +// + { + return ((TLinAddr)aDes & 0x3) == 0; + } + +// Channel class. +// For double buffering, TDmaDbChannel::DoQueue must be overridden. +// NE DMA has two sets of registers (base & work) - which is not supported by the original +#if defined(NE1_DMA_DOUBLE_BUFFER) +class TNE1DmaChannel : public TDmaDbChannel +#else +class TNE1DmaChannel : public TDmaSbChannel +#endif + { +public: + TNE1DmaChannel(); + void ProcessIrq(); + void ProcessErrorIrq(); + void StopTransfer(); + void Close(); + inline TBool IsIdle() const; + +private: +#if defined(NE1_DMA_DOUBLE_BUFFER) + virtual void DoQueue(const DDmaRequest& aReq); +#endif + virtual void QueuedRequestCountChanged(); + + inline void ProcessTC(TBool aClearStatus); + inline void ProcessEnd(TBool aClearStatus); + inline void ClearStatus(TUint32 aBitmask); + inline void HandleIsr(TBool aIsComplete); + +public: + TInt iHWCtrlBase;// Base address of H/W registers for this channel. + TInt iSubChannel;// Subchannel number (0-7) within H/W controller. + TInt iDMACHCReg; // The content of configuration (CHC) register for this channel. + TInt iTransferDataShift;//log2 of basic unit of transfer. See TDMAChannelLocator::iTransferShiftSize + + // The following members are public so that they can be + // modified by the TNaviEngineDmac class + + /** + This flag is set when the base register set is filled + + It allows the ISR to detect the case where a base to work + register set changeover has happened (END interrupt) but has been masked by + the completion of the work register set + */ + TBool iBaseValidSet; + + /** + This counter is incremented each time a LaunchTransfer is started + and decremented when the ISR handles the transfer complete (TC + bit). Ie. it does not keep count of the number of times the base + register set is filled. This allows missed TC interrupts to be + detected. + */ + TInt iTcIrqCount; + + /** + This spinlock is used to protect both the iBaseValidSet and iTcIrqCount + variables. It synchronises access between threads and the ISR. + + For the ISR the setting of iBaseValidSet must appear to be atomic with + the launch of the transfer. + + For iTcIrqCount The spinlock makes the transfer launch and subsequent + increase of the count appear atomic to the ISR. Otherwise it could + observe a completed transfer before the count was incremented or + vice-versa + */ + TSpinLock iIsrLock; + }; + +// +// Derived Controller Class +// + +using namespace Dma64; + +class TNaviEngineDmac : public TDmac + { +public: + TNaviEngineDmac(); + TInt Create(); + + friend void TNE1DmaChannel::HandleIsr(TBool); // Allow channel HandleIsr to call TDmac::HandleIsr +private: + // from TDmac (PIL pure virtual) + virtual void StopTransfer(const TDmaChannel& aChannel); + virtual TBool IsIdle(const TDmaChannel& aChannel); + virtual TUint MaxTransferLength(TDmaChannel& aChannel, TUint aSrcFlags, TUint aDstFlags, TUint32 aPslInfo); + virtual TUint AddressAlignMask(TDmaChannel& aChannel, TUint aSrcFlags, TUint aDstFlags, TUint32 aPslInfo); + // from TDmac (PIL virtual) + virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr); + virtual TInt InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs); + virtual TInt UpdateHwDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr, TUint32 aDstAddr, + TUint aTransferCount, TUint32 aPslRequestInfo); + virtual void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr); + virtual void AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr, + const SDmaDesHdr& aNewHdr); + virtual void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr); + // other + static void DMAC32_Isr(TAny* aThis, TInt aController, TInt aTcsMask, TInt aCompleted); + static void DMAC32_0_End_Isr(TAny* aThis); + static void DMAC32_0_Err_Isr(TAny* aThis); + static void DMAC32_2_End_Isr(TAny* aThis); + static void DMAC32_2_Err_Isr(TAny* aThis); + static void DMAC32_3_End_Isr(TAny* aThis); + static void DMAC32_3_Err_Isr(TAny* aThis); + static void InitHWChannel (ENaviEngineDmaController aNEController, TInt aGroup, TInt aSubChannel); + static void InitAllHWChannels (); + inline TDmaDesc* HdrToHwDes(const SDmaDesHdr& aHdr); +private: + static const SCreateInfo KInfo; +public: + + void PopulateWorkSet(TNE1DmaChannel& aChannel, const SDmaDesHdr& aHdr); + void LaunchTransfer(TNE1DmaChannel& aChannel, TBool aBaseSetValid); +#if defined(NE1_DMA_DOUBLE_BUFFER) + void PopulateBaseSet(TNE1DmaChannel& aChannel, const SDmaDesHdr& aHdr); + void ContinueTransfer(TNE1DmaChannel& aChannel, TBool aBaseSetValid); +#endif + + TNE1DmaChannel iChannels[EDmaChannelCount]; + static const SDmacCaps KCaps; + }; + +static TNaviEngineDmac Controller; + +// The following values report to the PIL what the PSL has been implemented +// to support, not necessarily what the hardware actually supports. +const SDmacCaps TNaviEngineDmac::KCaps = + {0, // TInt iChannelPriorities; + EFalse, // TBool iChannelPauseAndResume; + ETrue, // TBool iAddrAlignedToElementSize; + EFalse, // TBool i1DIndexAddressing; + EFalse, // TBool i2DIndexAddressing; + KDmaSyncAuto, // TUint iSynchronizationTypes; + KDmaBurstSizeAny, // TUint iBurstTransactions; + EFalse, // TBool iDescriptorInterrupt; + EFalse, // TBool iFrameInterrupt; + EFalse, // TBool iLinkedListPausedInterrupt; + EFalse, // TBool iEndiannessConversion; + KDmaGraphicsOpNone, // TUint iGraphicsOps; + EFalse, // TBool iRepeatingTransfers; + EFalse, // TBool iChannelLinking; + ETrue, // TBool iHwDescriptors; // DMAC does not really use Hw descriptors + EFalse, // TBool iSrcDstAsymmetry; + EFalse, // TBool iAsymHwDescriptors; + EFalse, // TBool iBalancedAsymSegments; + EFalse, // TBool iAsymCompletionInterrupt; + EFalse, // TBool iAsymDescriptorInterrupt; + EFalse, // TBool iAsymFrameInterrupt; + {0, 0, 0, 0, 0} // TUint32 iReserved[5]; + }; + + +const TDmac::SCreateInfo TNaviEngineDmac::KInfo = + { + ETrue, // iCapsHwDes + KDesCount, // iDesCount + sizeof(TDmaDesc), // iDesSize + EMapAttrSupRw | EMapAttrFullyBlocking // iDesChunkAttribs + }; + + +////////////////////////////////////////////////////////////////////////////// +// AXI 64bit DMAC - (Scatter Gather +////////////////////////////////////////////////////////////////////////////// + +class TNaviEngineDmac64Sg; + +class TNeSgChannel : public TDmaSgChannel + { + friend class TNaviEngineDmac64Sg; +public: + TNeSgChannel(); + TNeSgChannel(TInt aPslId); + + inline TUint BaseAddr() {return iBaseAddr;} + +#ifdef _DEBUG_PRINT_ISR + void Print(); +#endif + inline void Pause() + { + using namespace Channel; + AsspRegister::Modify32(iBaseAddr + Ctrl::KHoBase, NULL, Ctrl::KHtSetSuspend); + } + + inline void Resume() + { + using namespace Channel; + AsspRegister::Modify32(iBaseAddr + Ctrl::KHoBase, NULL, Ctrl::KHtClrSuspend); + } + + inline void MaskInterrupt() + { + using namespace Channel; + AsspRegister::Modify32(iBaseAddr + Cfg::KHoBase, NULL, Cfg::KHtEndMask|Cfg::KHtCompMask); + } + + inline TUint32 CurrSrcAddr() const + { + using namespace Channel; + return AsspRegister::Read32(iBaseAddr + RegSet::KHoBases[RegSet::ECurrent] + RegSet::KHoSrcAddr); + } + + inline TUint32 CurrDstAddr() const + { + using namespace Channel; + return AsspRegister::Read32(iBaseAddr + RegSet::KHoBases[RegSet::ECurrent] + RegSet::KHoDstAddr); + } + + inline TUint32 CurrByteCount() const + { + using namespace Channel; + return AsspRegister::Read32(iBaseAddr + RegSet::KHoBases[RegSet::ECurrent] + RegSet::KHoTranByte); + } + + inline TUint32 Status() const + { + return AsspRegister::Read32(iBaseAddr + Channel::Status::KHoBase); + } + + inline TUint32 Config() const + { + return AsspRegister::Read32(iBaseAddr + Channel::Cfg::KHoBase); + } + + inline TUint32 NextLink() const + { + return AsspRegister::Read32(iBaseAddr + Channel::KHoNxtLnkAddr); + } + + inline TUint32 CurrLink() const + { + return AsspRegister::Read32(iBaseAddr + Channel::KHoCurrtLnkAddr); + } + + virtual void QueuedRequestCountChanged(); + + inline TBool IsIdle() const + { + const TUint channelStatus = Status(); + using namespace Channel::Status; + const TBool isIdle = (channelStatus & (KHtEnabled | KHtDescLoad)) == 0; + return isIdle; + } + + void Transfer(TDma64Desc* aHwDes); + void Close(); + +private: + TUint32 iBaseAddr; + + TInt iTransferCount; + TSpinLock iLock; + }; + +/** +Represents the 64 bit controller on the AXI bus - in scatter gather +mode. The controller supports both scatter gather and double buffered +mode but the framework dicatates that separate logical DMACs are +required for each mode of operation. +*/ +class TNaviEngineDmac64Sg : public TDmac + { +public: + TNaviEngineDmac64Sg(); + TInt Create(); + +private: + // from TDmac (PIL pure virtual) + virtual void StopTransfer(const TDmaChannel& aChannel); + virtual TBool IsIdle(const TDmaChannel& aChannel); + virtual TUint MaxTransferLength(TDmaChannel& aChannel, TUint aSrcFlags, TUint aDstFlags, TUint32 aPslInfo); + virtual TUint AddressAlignMask(TDmaChannel& aChannel, TUint aSrcFlags, TUint aDstFlags, TUint32 aPslInfo); + // from TDmac (PIL virtual) + virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr); + virtual TInt InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs); + virtual TInt UpdateHwDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr, TUint32 aDstAddr, + TUint aTransferCount, TUint32 aPslRequestInfo); + virtual void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr); + virtual void AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr, + const SDmaDesHdr& aNewHdr); + virtual void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr); + // other + static void IsrEnd(TAny* aThis); + static void IsrErr(TAny* aThis); + + inline TDma64Desc* HdrToHwDes(const SDmaDesHdr& aHdr); + static void JoinHwDes(TDma64Desc& aHwDes, const TDma64Desc& aNextHwDes); + +private: + static const SCreateInfo KInfo; + +public: + TNeSgChannel iChannels[Dma64::KChannelCount]; + static const SDmacCaps KCaps; + }; + +static TNaviEngineDmac64Sg Controller64; + + +// The following values report to the PIL what the PSL has been implemented +// to support, not necessarily what the hardware actually supports. +const SDmacCaps TNaviEngineDmac64Sg::KCaps = + {0, // TInt iChannelPriorities; + EFalse, // TBool iChannelPauseAndResume; + EFalse, // TBool iAddrAlignedToElementSize; + EFalse, // TBool i1DIndexAddressing; + EFalse, // TBool i2DIndexAddressing; + KDmaSyncAuto, // TUint iSynchronizationTypes; + KDmaBurstSizeAny, // TUint iBurstTransactions; + EFalse, // TBool iDescriptorInterrupt; + EFalse, // TBool iFrameInterrupt; + EFalse, // TBool iLinkedListPausedInterrupt; + EFalse, // TBool iEndiannessConversion; + KDmaGraphicsOpNone, // TUint iGraphicsOps; + EFalse, // TBool iRepeatingTransfers; + EFalse, // TBool iChannelLinking; + ETrue, // TBool iHwDescriptors; + EFalse, // TBool iSrcDstAsymmetry; + EFalse, // TBool iAsymHwDescriptors; + EFalse, // TBool iBalancedAsymSegments; + EFalse, // TBool iAsymCompletionInterrupt; + EFalse, // TBool iAsymDescriptorInterrupt; + EFalse, // TBool iAsymFrameInterrupt; + {0, 0, 0, 0, 0} // TUint32 iReserved[5]; + }; + + +const TDmac::SCreateInfo TNaviEngineDmac64Sg::KInfo = + { + ETrue, // iCapsHwDes + KDesCount, // iDesCount + sizeof(TDma64Desc), // iDesSize + EMapAttrSupRw | EMapAttrFullyBlocking // iDesChunkAttribs + }; + + +TNaviEngineDmac::TNaviEngineDmac() +// +// Constructor. +// + : TDmac(KInfo) + { + } + +TInt TNaviEngineDmac::Create() +// +// Second phase construction. +// + { + TInt r = TDmac::Create(KInfo); // Base class Create() + if (r == KErrNone) + { + // Read KDMAChannelLocator constants and populate the values in channel objects. + for (TInt i=0; i < EDma32ChannelCount; ++i) + { + TUint ctrlBase = 0; + switch (KDMAChannelLocator[i].iDMACtrl) + { + case EDmaCtrlExBus: ctrlBase = KDMACExBusBase; break; + case EDMACtrl32: ctrlBase = KDMAC32Base; break; + default: __DMA_CANT_HAPPEN(); + } + iChannels[i].iHWCtrlBase = ctrlBase + KDMAChannelLocator[i].iGroup * KDMAGroupOffset + + KDMAChannelLocator[i].iSubChannel * KDMAChannelOffset; + iChannels[i].iSubChannel = KDMAChannelLocator[i].iSubChannel; + iChannels[i].iDMACHCReg = KDMAChannelLocator[i].iDMACHCReg | iChannels[i].iSubChannel; + iChannels[i].iTransferDataShift = KDMAChannelLocator[i].iTransferShiftSize; + iFreeHdr = iFreeHdr->iNext; + } + + //Bind DMA interrupt for channels we support + TInt irqh0 = Interrupt::Bind(KIntDMAC32_0_End, DMAC32_0_End_Isr, this); __DMA_ASSERTA(irqh0>=0); + TInt irqh1 = Interrupt::Bind(KIntDMAC32_0_Err, DMAC32_0_Err_Isr, this); __DMA_ASSERTA(irqh1>=0); + TInt irqh2 = Interrupt::Bind(KIntDMAC32_2_End, DMAC32_2_End_Isr, this); __DMA_ASSERTA(irqh2>=0); + TInt irqh3 = Interrupt::Bind(KIntDMAC32_2_Err, DMAC32_2_Err_Isr, this); __DMA_ASSERTA(irqh3>=0); + TInt irqh4 = Interrupt::Bind(KIntDMAC32_3_End, DMAC32_3_End_Isr, this); __DMA_ASSERTA(irqh4>=0); + TInt irqh5 = Interrupt::Bind(KIntDMAC32_3_Err, DMAC32_3_Err_Isr, this); __DMA_ASSERTA(irqh5>=0); + + + InitAllHWChannels(); + + r = Interrupt::Enable(irqh0); __DMA_ASSERTA(r==KErrNone); + r = Interrupt::Enable(irqh1); __DMA_ASSERTA(r==KErrNone); + r = Interrupt::Enable(irqh2); __DMA_ASSERTA(r==KErrNone); + r = Interrupt::Enable(irqh3); __DMA_ASSERTA(r==KErrNone); + r = Interrupt::Enable(irqh4); __DMA_ASSERTA(r==KErrNone); + r = Interrupt::Enable(irqh5); __DMA_ASSERTA(r==KErrNone); + } + return r; + } + +// Initialises all H/W channels. This will make sure they are off on soft restart. +void TNaviEngineDmac::InitAllHWChannels() + { + int i,j; + for (i=0;i(aChannel); + TNE1DmaChannel& channel = static_cast(mutableChannel); + + const TBool isIsr = (NKern::CurrentContext() == NKern::EInterrupt); + TInt irq = 0; + if(!isIsr) // If we are in ISR context, assume that the lock is already held + { + irq = __SPIN_LOCK_IRQSAVE(channel.iIsrLock); + } + + // The fragment descriptor (src/dest address, size) should be placed into either "Work Set" or "Base Set" + // depending on the actual state of the H/W + if (IsIdle(channel)) + { + // The channel is idle, for the (most likely) reason that both "Work Set" and "Base Set" transfers are + // completed since the last time we run this function. + #ifdef _DEBUG + Transfer_IdleOnStart++; + #endif + PopulateWorkSet(channel, aHdr); // Populate "Work Set" + LaunchTransfer(channel, EFalse); // Start the transfer, base set is invalid + } + else + { + // "Work Set" transfer is still going on. It seems we will manage to place + // the next fragment in time for continious traffic flow. + #ifdef _DEBUG + Transfer_NotIdleOnStart++; + #endif + PopulateBaseSet(channel, aHdr); // Populate "Base Set" + ContinueTransfer(channel, ETrue);// Indicate Base Set is valid (bvalid = ETrue) + + // We should expect here that the "work set" traffic is still in progress. + // Once it is completed, "Base Set" content is copied into "Work Set" and the traffic will go on. + // However, there is a corner case where we configure "Base Set" too late. + // Therefore, check if transfer is still active. + if (IsIdle(channel)) + { + // There is no DMA traffic. There could be two reason for that. Either, + // 1. The transfer we have just configured in "Base Set" has already completed, or + // 2. We configured base set too late, after "Work Set" transfer has already finished. + + // Check BVALID bit + // if its now clear, then it was set in time, if it's + // still set it was set too late + const TUint32 dchs = AsspRegister::Read32(channel.iHWCtrlBase+KHoDMACHS); + const TBool bvalidSet = dchs & KHtDMACHS_BVALID; + + if (!bvalidSet) + { + DMA_PSL_CHAN_TRACE_STATIC(channel, "Base set transferred already"); + #ifdef _DEBUG + Transfer_MatchWorkSetTrue++; + #endif + } + else + { + DMA_PSL_CHAN_TRACE_STATIC(channel, "Too late for base set"); + + // BVALID bit was set after "Work Set" transfer completed, and DMA H/W didn't + // copy the content of "Base Set" into "Work Set". We have to re-launch the transfer. + // This time we have to configure "Work Set" + #ifdef _DEBUG + Transfer_MatchWorkSetFalse++; + #endif + PopulateWorkSet(channel, aHdr); // Populate "Work Set". + LaunchTransfer(channel, EFalse); // Start the transfer, "Base Set" is invalid. + } + } + } + if(!isIsr) + { + __SPIN_UNLOCK_IRQRESTORE(channel.iIsrLock, irq); + } + } +#else +void TNaviEngineDmac::Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr) +// +// Initiates a (previously constructed) request on a specific channel. +// + { + TDmaChannel& mutableChannel = const_cast(aChannel); + TNE1DmaChannel& channel = static_cast(mutableChannel); + + DMA_PSL_CHAN_TRACE_STATIC1(channel, "TNaviEngineDmac::Transfer des=0x%08X", HdrToHwDes(aHdr)); + + const TBool isIsr = (NKern::CurrentContext() == NKern::EInterrupt); + TInt irq = 0; + if(!isIsr) // If we are in ISR context, assume that the lock is already held + { + irq = __SPIN_LOCK_IRQSAVE(channel.iIsrLock); + } + + // The fragment descriptor (src/dest address, size) should be placed into either "Work Set" or "Base Set" + // depending on the actual state of the H/W + __NK_ASSERT_ALWAYS(IsIdle(channel)); + PopulateWorkSet(channel, aHdr); // Populate "Work Set" + LaunchTransfer(channel, EFalse); // Start the transfer, base set is invalid + if(!isIsr) + { + __SPIN_UNLOCK_IRQRESTORE(channel.iIsrLock, irq); + } + } +#endif + + +void TNaviEngineDmac::StopTransfer(const TDmaChannel& aChannel) +// +// Stops a running channel. +// + { + TDmaChannel& mutableChannel = const_cast(aChannel); + TNE1DmaChannel& channel = static_cast(mutableChannel); + + __KTRACE_OPT(KDMA, Kern::Printf("TNaviEngineDmac::StopTransfer channel=%d", channel.PslId())); + + channel.StopTransfer(); + + __KTRACE_OPT(KDMA, Kern::Printf("(aChannel); + TNE1DmaChannel& channel = static_cast(mutableChannel); + + const TBool idle = channel.IsIdle(); + __KTRACE_OPT(KDMA, Kern::Printf(">Dmac::IsIdle channel=%d, idle=%d", channel.PslId(), idle)); + return idle; + } + +// Places the descriptor into "Work Set" +void TNaviEngineDmac::PopulateWorkSet(TNE1DmaChannel& aChannel, const SDmaDesHdr& aHdr) + { + TDmaDesc* pD = HdrToHwDes(aHdr); + __KTRACE_OPT(KDMA, Kern::Printf("TNaviEngineDmac::PopulateWorkSet channel=%d des=0x%08X", + aChannel.PslId(), pD)); + + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMACHC, aChannel.iDMACHCReg); //configure channel + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMASAW, pD->iSrcAddr); //source addr + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMADAW, pD->iDestAddr); //dest addr + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMATCW, (pD->iCount>>aChannel.iTransferDataShift)-1); //transfer counter + } + +// Starts the transfer. +// @pre The chanel is idle. +// @arg aBaseSetValid if true, BVALID bit should be set. +// @pre iIsrLock must be held +void TNaviEngineDmac::LaunchTransfer(TNE1DmaChannel& aChannel, TBool aBaseSetValid) + { + __KTRACE_OPT(KDMA, Kern::Printf("TNaviEngineDmac::LaunchTransfer channel=%d", aChannel.PslId())); + TInt val = KHtDMACHS_EN|KHtDMACHS_EN_EN; + if (TUint(aChannel.iDMACHCReg ^ aChannel.iSubChannel) == (TUint)KHvDMACHC_SW) + val |=KHtDMACHS_STG; + if (aBaseSetValid) + val|=KHtDMACHS_BVALID; + + aChannel.iBaseValidSet = aBaseSetValid; + + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMACHS, val); + + aChannel.iTcIrqCount++; + DMA_PSL_CHAN_TRACE_STATIC1(aChannel, "inc iTcIrqCount to %d", aChannel.iTcIrqCount); + } + +#if defined(NE1_DMA_DOUBLE_BUFFER) +// Places the descriptor into "Base Set" +void TNaviEngineDmac::PopulateBaseSet(TNE1DmaChannel& aChannel, const SDmaDesHdr& aHdr) + { + TDmaDesc* pD = HdrToHwDes(aHdr); + __KTRACE_OPT(KDMA, Kern::Printf(">TNaviEngineDmac::PopulateBaseSet channel=%d des=0x%08X", aChannel.PslId(), pD)); + + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMASAB, pD->iSrcAddr); // Source addr + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMADAB, pD->iDestAddr); // Dest addr + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMATCB, (pD->iCount>>aChannel.iTransferDataShift)-1); // Transfer counter + } + +// @pre DMA transfer is in progress. +// @arg aBaseSetValid if true, BVALID bit should be set. +// @pre iIsrLock must be held +void TNaviEngineDmac::ContinueTransfer(TNE1DmaChannel& aChannel, TBool aBaseSetValid) + { + __KTRACE_OPT(KDMA, Kern::Printf("TNaviEngineDmac::ContinueTransfer channel=%d", aChannel.PslId())); + TInt val = 0; + if (TUint(aChannel.iDMACHCReg ^ aChannel.iSubChannel) == (TUint)KHvDMACHC_SW) + val |=KHtDMACHS_STG; // Set software trigger + if (aBaseSetValid) + { + __NK_ASSERT_DEBUG(!aChannel.iBaseValidSet); + aChannel.iBaseValidSet = ETrue; + val|=KHtDMACHS_BVALID; + } + + if (val) + { + AsspRegister::Write32(aChannel.iHWCtrlBase+KHoDMACHS, val); + } + } + +// As in TDmaDbChannel, except for EIdle state as we have place the 1st and the 2nd +// fragment into different registers. +void TNE1DmaChannel::DoQueue(const DDmaRequest& aReq) + { + TNaviEngineDmac* controller = (TNaviEngineDmac*)iController; + + switch (iState) + { + case EIdle: + { + controller->PopulateWorkSet(*this, *iCurHdr); + const TInt irq = __SPIN_LOCK_IRQSAVE(iIsrLock); + if (iCurHdr->iNext) + { + controller->PopulateBaseSet(*this, *(iCurHdr->iNext)); + controller->LaunchTransfer(*this, ETrue);//BaseSetValid=True + iState = ETransferring; + } + else + { + controller->LaunchTransfer(*this, EFalse);//BaseSetValid=False + iState = ETransferringLast; + } + __SPIN_UNLOCK_IRQRESTORE(iIsrLock, irq); + break; + } + case ETransferring: + // nothing to do + break; + case ETransferringLast: + iController->Transfer(*this, *(aReq.iFirstHdr)); + iState = ETransferring; + break; + default: + __DMA_CANT_HAPPEN(); + } + } +#endif + +TNE1DmaChannel::TNE1DmaChannel() + :iBaseValidSet(EFalse), iTcIrqCount(0), iIsrLock(TSpinLock::EOrderGenericIrqHigh0) + {} + +/** +Handles normal interrupts as well as recovering from missed interrupts. +It must therefore be called during an ISR, for every valid, open channel +on a DMAC .ie not just channels which have status bits set. +*/ +void TNE1DmaChannel::ProcessIrq() + { + // The spinlock protects access to the iBaseValidSet flag + // This is needed because it is possible for TNaviEngineDmac::Transfer to + // attempt to populate the base set, set iBaseValidSet, but then + // realize it was too late, and have to unset it. + const TInt irq = __SPIN_LOCK_IRQSAVE(iIsrLock); + + // check that channel is open + if(iController == NULL) + { + __SPIN_UNLOCK_IRQRESTORE(iIsrLock, irq); + return; + } + + const TInt irqCount = iTcIrqCount; + __NK_ASSERT_ALWAYS(irqCount >= 0); + __NK_ASSERT_ALWAYS(irqCount < 3); + + TUint32 dchs = AsspRegister::Read32(iHWCtrlBase+KHoDMACHS); + + // Detect if we have missed 1 TC interrupt. + // This can happen when there is one transfer in progress, + // and the channel attempts to populate the base reg set, but + // is too late and launches a new transfer. The second transfer + // may then complete during the ISR of the first, or the ISR may + // not run untill after the second has already completed. + if((irqCount > 0) && IsIdle()) + { + // Reread status now that we have observed channel as idle. + // If a transfer completed between the first read and now, we + // can handle that as a normal interrupt instead of as a + // missed interrupt. This is not essential, just neater + dchs = AsspRegister::Read32(iHWCtrlBase+KHoDMACHS); + if(irqCount == 1) // There may or may not be a missed IRQ + { + if((dchs & KHtDMACHS_TC) == 0) + { + DMA_PSL_CHAN_TRACE1("Channel had missed TC IRQ irqs=%d", irqCount); + ProcessTC(EFalse); + } + } + else if(irqCount == 2) // There is 1 missed and 1 normal IRQ + { + DMA_PSL_CHAN_TRACE1("Channel had missed TC IRQ irqs=%d", irqCount); + ProcessTC(EFalse); + + // Ensure that remaining IRQ will be dealt with in next block + __NK_ASSERT_ALWAYS((dchs & KHtDMACHS_TC)); + } + else + { + // It should not be possible for there to be more than 2 + // outstanding transfers launched + FAULT(); + } + } + + // Deal with normal interrupts + if (dchs&KHtDMACHS_TC) + { + // ISR should not be able to observe the BVALID bit itself + // since TNaviEngineDmac::Transfer should hold iIsrLock whilst + // it decides if it was set in time + __NK_ASSERT_DEBUG(!(dchs & KHtDMACHS_BVALID)); + + // Here we find out if a base-set-copy (END) interrupt has + // been missed. If a TC comes shortly after an END IRQ then + // it would be impossible to tell by looking at the status + // register alone + if(iBaseValidSet) + { + DMA_PSL_CHAN_TRACE("END irq missed "); + ProcessEnd(EFalse); + } + ProcessTC(ETrue); + } + else if (dchs&KHtDMACHS_END) + { + ProcessEnd(ETrue); + } + + __SPIN_UNLOCK_IRQRESTORE(iIsrLock, irq); + } + +void TNE1DmaChannel::ProcessErrorIrq() + { + const TInt irq = __SPIN_LOCK_IRQSAVE(iIsrLock); + + // check that channel is open + if(iController == NULL) + { + __SPIN_UNLOCK_IRQRESTORE(iIsrLock, irq); + return; + } + + // reset channel + ClearStatus(KHtDMACHS_FCLR); + TInt badIrqCount = iTcIrqCount; + iTcIrqCount = 0; + + if(iBaseValidSet) + { + iBaseValidSet = EFalse; + badIrqCount++; + } + + // complete all outstanding requests as being in error + for(TInt i=0; i < badIrqCount; i++) + { + HandleIsr(EFalse); + } + + __SPIN_UNLOCK_IRQRESTORE(iIsrLock, irq); + } + +/** +Handle a transfer complete (work set transfer complete and base set was +empty) on this channel. + +@param aClearStatus - Status bits should be cleared +*/ +void TNE1DmaChannel::ProcessTC(TBool aClearStatus) + { + // iTcIrqCount may be zero if StopTransfer were called + // between the transfer being started and the ISR running + if(iTcIrqCount>0) + { + DMA_PSL_CHAN_TRACE1("dec iTcIrqCount to %d", iTcIrqCount); + iTcIrqCount--; + DMA_PSL_CHAN_TRACE("TC"); + HandleIsr(ETrue); + } + + __NK_ASSERT_DEBUG(iTcIrqCount >= 0); + + if(aClearStatus) + ClearStatus(KHtDMACHS_TC|KHtDMACHS_END); //Traffic completed BVALID=OFF + } + +/** +Handle a END (transfer complete, base set loaded in to work set) on this channel. + +@param aClearStatus - Status bit should be cleared +*/ +void TNE1DmaChannel::ProcessEnd(TBool aClearStatus) + { + if(iBaseValidSet) + { + DMA_PSL_CHAN_TRACE("END"); + iBaseValidSet = EFalse; + HandleIsr(ETrue); + } + + if(aClearStatus) + ClearStatus(KHtDMACHS_END); //Traffic completed BVALID=ON + } + +/** +@param aBitmask The bits to be cleared in this channel's status register +*/ +void TNE1DmaChannel::ClearStatus(TUint32 aBitmask) + { + if (TUint((this->iDMACHCReg) ^ (this->iSubChannel)) == (TUint)KHvDMACHC_SW) + aBitmask |= KHtDMACHS_STG; //Add STG for S/W channel + + AsspRegister::Write32(iHWCtrlBase+KHoDMACHS, aBitmask); //End-of-Int + } + +/** +Call HandleIsr for this channel +*/ +void TNE1DmaChannel::HandleIsr(TBool aIsComplete) + { + // iController must be casted so that the private method + // TDmac::HandleIsr can be called since this method is + // a friend of TNaviEngineDmac, but not TDmac. + static_cast(iController)->HandleIsr(*this, EDmaCallbackRequestCompletion, aIsComplete); + } + +/** +Stop transfer for this channel +*/ +void TNE1DmaChannel::StopTransfer() + { + const TInt irq = __SPIN_LOCK_IRQSAVE(iIsrLock); + // At this point, device driver should have cancelled DMA request. + + // The procedure for clearing the EN bit to 0 via CPU access during DMA transfer (EN bit = 1) + TUint32 dmaCHS = AsspRegister::Read32(iHWCtrlBase+KHoDMACHS); + + // Read the DCHSn register to be cleared at the relevant channel and confirm that + // both the RQST and ACT bits are cleared to 0. If either or both of them are 1, + // perform polling until their values become 0.. + // OR unless KHtDMACHS_EN is already cleared by the HW at the end of the transfer - + // while we're polling... + while( (dmaCHS & KHtDMACHS_EN) && + dmaCHS & (KHtDMACHS_RQST | KHtDMACHS_ACT) ) + { + dmaCHS = AsspRegister::Read32(iHWCtrlBase+KHoDMACHS); + } + + // enable writing to EN bit.. + dmaCHS |= KHtDMACHS_EN_EN; + AsspRegister::Write32(iHWCtrlBase+KHoDMACHS, dmaCHS); + + // clear the EN bit to 0 + // and set the FCLR bit of the DCHSn register to 1. + dmaCHS &= (~KHtDMACHS_EN); + dmaCHS |= KHtDMACHS_FCLR; + AsspRegister::Write32(iHWCtrlBase+KHoDMACHS, dmaCHS); + + // check that channel is idle, and status bits have been cleared + __NK_ASSERT_ALWAYS(IsIdle()); + dmaCHS = AsspRegister::Read32(iHWCtrlBase+KHoDMACHS); + __NK_ASSERT_ALWAYS((dmaCHS & (KHtDMACHS_TC | KHtDMACHS_END)) == 0); + __NK_ASSERT_ALWAYS(iTcIrqCount >=0); + + // given the above checks, clear the iTcIrqCount and iBaseValidSet so + // that the ISR won't mistakenly think there are missed interrupts + iTcIrqCount = 0; + iBaseValidSet = EFalse; + + __SPIN_UNLOCK_IRQRESTORE(iIsrLock, irq); + } + +/** +@pre Channel has been stopped +*/ +void TNE1DmaChannel::Close() + { + // The lock prevents a channel being closed + // during an ISR. + const TInt irq = __SPIN_LOCK_IRQSAVE(iIsrLock); + DMA_PSL_CHAN_TRACE("Close"); + + // Check that the channel was Idle and Stopped + __NK_ASSERT_ALWAYS(IsIdle()); + __NK_ASSERT_ALWAYS(iTcIrqCount == 0); + __NK_ASSERT_ALWAYS(!iBaseValidSet); + + + // Here we clear iController in advance of the PIL + // If we did not do this, then when we release the lock, the ISR + // could observe it as non-null, proceed, but then have the PIL + // clear it mid-isr + iController = NULL; + + __SPIN_UNLOCK_IRQRESTORE(iIsrLock, irq); + } + +TBool TNE1DmaChannel::IsIdle() const + { + TUint status = AsspRegister::Read32(iHWCtrlBase+KHoDMACHS); + return !(status & KHtDMACHS_EN); + } + + +void TNE1DmaChannel::QueuedRequestCountChanged() + { + const TInt qreqs = __e32_atomic_load_acq32(&iQueuedRequests); + DMA_PSL_CHAN_TRACE1("TNE1DmaChannel::QueuedRequestCountChanged() %d", qreqs); + __DMA_ASSERTA(qreqs >= 0); + } + + +TUint TNaviEngineDmac::MaxTransferLength(TDmaChannel& aChannel, TUint /*aSrcFlags*/, TUint /*aDstFlags*/, + TUint32 /*aPslInfo*/) +// +// Returns the maximum transfer size for a given transfer. +// + { + TNE1DmaChannel& channel = (TNE1DmaChannel&)aChannel; + return (1u<iSrcAddr = (src.iFlags & KDmaPhysAddr) ? src.iAddr : Epoc::LinearToPhysical(src.iAddr); + __DMA_ASSERTD(pD->iSrcAddr != KPhysAddrInvalid); + pD->iDestAddr = (dst.iFlags & KDmaPhysAddr) ? dst.iAddr : Epoc::LinearToPhysical(dst.iAddr); + __DMA_ASSERTD(pD->iDestAddr != KPhysAddrInvalid); + pD->iCount = aTransferArgs.iTransferCount; + + __KTRACE_OPT(KDMA, Kern::Printf(" src=0x%08X dest=0x%08X count=%d", + pD->iSrcAddr, pD->iDestAddr, pD->iCount)); + return KErrNone; + } + + +TInt TNaviEngineDmac::UpdateHwDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr, TUint32 aDstAddr, + TUint aTransferCount, TUint32 aPslRequestInfo) +// +// Updates (from the passed in arguments) fields of the descriptor. This +// function is called by the PIL in ISR context. +// + { + TDmaDesc* pD = HdrToHwDes(aHdr); + + __KTRACE_OPT(KDMA, Kern::Printf("TNaviEngineDmac::UpdateHwDes 0x%08X", pD)); + + // Unaligned descriptor? Bug in generic layer! + __DMA_ASSERTD(IsHwDesAligned(pD)); + + // Addresses passed into this function are always physical ones. + if (aSrcAddr != KPhysAddrInvalid) + { + __KTRACE_OPT(KDMA, Kern::Printf(" Changing src addr, old: 0x%08X new: 0x%08X", + pD->iSrcAddr, aSrcAddr)); + pD->iSrcAddr = aSrcAddr; + } + if (aDstAddr != KPhysAddrInvalid) + { + __KTRACE_OPT(KDMA, Kern::Printf(" Changing dst addr, old: 0x%08X new: 0x%08X", + pD->iDestAddr, aDstAddr)); + pD->iDestAddr = aDstAddr; + } + if (aTransferCount != 0) + { + __KTRACE_OPT(KDMA, Kern::Printf(" Changing xfer count, old: %d new: %d", + pD->iCount, aTransferCount)); + pD->iCount = aTransferCount; + } + if (aPslRequestInfo != 0) + { + __KTRACE_OPT(KDMA, Kern::Printf(" aPslRequestInfo specified (0x%08X) but ignored", + aPslRequestInfo)); + } + + __KTRACE_OPT(KDMA, Kern::Printf(" src=0x%08X dst=0x%08X count=%d", + pD->iSrcAddr, pD->iDestAddr, pD->iCount)); + + return KErrNone; + } + + +void TNaviEngineDmac::ChainHwDes(const SDmaDesHdr& /*aHdr*/, const SDmaDesHdr& /*aNextHd*/) +// +// Chains hardware descriptors together. +// DMAC32 doesn't support linked descriptors, therefore there is nothing we have to do here. +// + { + } + + +void TNaviEngineDmac::AppendHwDes(const TDmaChannel& /*aChannel*/, const SDmaDesHdr& /*aLastHdr*/, + const SDmaDesHdr& /*aNewHdr*/) +// +// Appends a descriptor to the chain while the channel is running. +// DMAC32 doesn't support linked descriptors, therefore there is nothing we have to do here. +// + { + } + + +void TNaviEngineDmac::UnlinkHwDes(const TDmaChannel& /*aChannel*/, SDmaDesHdr& /*aHdr*/) +// +// Unlink the last item in the h/w descriptor chain from a subsequent chain that it was possibly linked to. +// DMAC32 doesn't support linked descriptors, therefore there is nothing we have to do here. +// + { + } + + + void TNaviEngineDmac::DMAC32_Isr(TAny* aThis, TInt aController, TInt aDmaStat, TInt aCompleted) + // + // Generic part for all DMA32 interrupts. + // Reads the interrupt identification and calls back into the base class + // interrupt service handler with the channel identifier and an indication whether the + // transfer completed correctly or with an error. + // + { + DMA_PSL_TRACE("Begin ISR"); + + TNaviEngineDmac& me = *static_cast(aThis); + int i; + + if (aCompleted) // Transfer-completed interrupt has occured + { + // Go through the all eight subchannels to check which event has occured. + for (i=0;i= EDma32ChannelCount) __DMA_CANT_HAPPEN(); + #endif + + // Skip unused physical channels + // .ie those with no corresponding entry + // in KDMAChannelLocator + if(channel == -1) + continue; + + TNE1DmaChannel& ne1Chan = me.iChannels[channel]; + + ne1Chan.ProcessIrq(); + } + } + else // Error interrupt has occured. aDmaStat is not valid. Should read H/W registers. + { + // Go through the all eight subchannels to check which event has occured. + for (i=0;i= EDma32ChannelCount) __DMA_CANT_HAPPEN(); + #endif + + TNE1DmaChannel& ne1Chan = me.iChannels[channel]; + ne1Chan.ProcessErrorIrq(); + } + } + } +#if defined(NE1_DMA_DOUBLE_BUFFER) + #ifdef _DEBUG + InterruptCounter_DMA32++; + #endif +#endif + } + + + void TNaviEngineDmac::DMAC32_0_End_Isr(TAny* aThis) + { + TInt stat = (TInt)AsspRegister::Read32(KDMAC32Base+0*KDMAGroupOffset+KHoDMASTAT); + DMAC32_Isr(aThis, 0, stat, 1); + } + void TNaviEngineDmac::DMAC32_2_End_Isr(TAny* aThis) + { + TInt stat = (TInt)AsspRegister::Read32(KDMAC32Base+2*KDMAGroupOffset+KHoDMASTAT); + DMAC32_Isr(aThis, 2, stat, 1); + } + void TNaviEngineDmac::DMAC32_3_End_Isr(TAny* aThis) + { + TInt stat = (TInt)AsspRegister::Read32(KDMAC32Base+3*KDMAGroupOffset+KHoDMASTAT); + DMAC32_Isr(aThis, 3, stat, 1); + } + + void TNaviEngineDmac::DMAC32_0_Err_Isr(TAny* aThis) + { + DMAC32_Isr(aThis, 0, 0, 0); + } +void TNaviEngineDmac::DMAC32_2_Err_Isr(TAny* aThis) + { + DMAC32_Isr(aThis, 2, 0, 0); + } +void TNaviEngineDmac::DMAC32_3_Err_Isr(TAny* aThis) + { + DMAC32_Isr(aThis, 3, 0, 0); + } + +inline TDmaDesc* TNaviEngineDmac::HdrToHwDes(const SDmaDesHdr& aHdr) +// +// Changes return type of base class call. +// + { + return static_cast(TDmac::HdrToHwDes(aHdr)); + } + +// +// Channel Opening/Closing (Channel Allocator) +// +TDmaChannel* DmaChannelMgr::Open(TUint32 aOpenId, TBool aDynChannel, TUint aPriority) + { + __KTRACE_OPT(KDMA, Kern::Printf("DmaChannelMgr::Open Id=%d DynChannel=%d Priority=%d", + aOpenId, aDynChannel, aPriority)); + + __DMA_ASSERTA(aOpenId < static_cast(EDmaChannelCount)); + + if (aDynChannel) + { + __KTRACE_OPT(KPANIC, Kern::Printf("DmaChannelMgr::Open failed as dynamic channel allocation is not supported")); + return NULL; + } + + const ENaviEngineDmaController controllerId = KDMAChannelLocator[aOpenId].iDMACtrl; + + TUint32 pslId = NULL; + TDmaChannel* pC = NULL; + TDmac* dmac = NULL; + const SDmacCaps* caps = NULL; + + switch (controllerId) + { + case EDmaCtrlExBus: + // fall through, EDmaCtrlExBus and EDMACtrl32 contollers work the same way + case EDMACtrl32: + pslId = aOpenId; + pC = Controller.iChannels + pslId; + dmac = &Controller; + caps = &TNaviEngineDmac::KCaps; + break; + case EDmaCtrl64: + pslId = aOpenId - EDma64MemToMem0; + pC = Controller64.iChannels + pslId; + dmac = &Controller64; + caps = &TNaviEngineDmac64Sg::KCaps; + break; + default: + __DMA_CANT_HAPPEN(); + } + + if (pC->IsOpened()) + { + pC = NULL; + } + else + { + pC->iController = dmac; + pC->iDmacCaps = caps; + pC->iPslId = pslId; + // Note: Dynamic channel allocation not currently supported by PIL + pC->iDynChannel = EFalse; + // Note: Channel priority setting not currently supported by PIL + pC->iPriority = aPriority; + } + + return pC; + } + +void DmaChannelMgr::Close(TDmaChannel* aChannel) + { + if(aChannel->iController == &Controller) + { + // Check if this is a TNE1DmaChannel + TNE1DmaChannel* channel = static_cast(aChannel); + channel->Close(); + } + else if(aChannel->iController == &Controller64) + { + TNeSgChannel* channel = static_cast(aChannel); + channel->Close(); + } + else + { + FAULT(); + } + } + +TInt DmaChannelMgr::StaticExtension(TInt /* aCmd */, TAny* /* aArg */) + { + return KErrNotSupported; + } + +TNeSgChannel::TNeSgChannel() + :TDmaSgChannel(), iBaseAddr(NULL), iTransferCount(0), iLock(TSpinLock::EOrderGenericIrqHigh0) + { + FUNC_LOG; + } + +TNeSgChannel::TNeSgChannel(TInt aPslId) + :TDmaSgChannel(), iTransferCount(0), iLock(TSpinLock::EOrderGenericIrqHigh0) + { + FUNC_LOG; + iPslId = aPslId; + iBaseAddr = Channel::KHoBases[iPslId] + KHwDMAC64Base; + } + +void TNeSgChannel::Transfer(TDma64Desc* aHwDes) + { + __DMA_ASSERTD(aHwDes); +#ifdef _DEBUG_PRINT + Print(); + aHwDes->Print(); +#endif + const TPhysAddr descAddr = iController->HwDesLinToPhys(aHwDes); + + __NK_ASSERT_DEBUG(IsIdle()); + // We shouldn't be clobbering the "next link" register. + // When a descriptor chain has completed the + // register should be empty. + __NK_ASSERT_DEBUG(NextLink() == NULL); + + const TBool isIsr = (NKern::CurrentContext() == NKern::EInterrupt); + TInt irq = 0; + if(!isIsr) // If we are in ISR context, assume that the lock is already held + { + irq = __SPIN_LOCK_IRQSAVE(iLock); + } + DMA_PSL_CHAN_TRACE1("Transfer iTransferCount %d", iTransferCount); + iTransferCount++; + + AsspRegister::Write32(iBaseAddr + Channel::KHoNxtLnkAddr, descAddr); + AsspRegister::Modify32(iBaseAddr + Channel::Cfg::KHoBase, 0, Channel::Cfg::KHtLinkMode); + AsspRegister::Modify32(iBaseAddr + Channel::Ctrl::KHoBase, 0, Channel::Ctrl::KHtSetEnable); + +#ifdef _DEBUG_PRINT + { + TUint32 status = NULL; + do + { + status = Status(); + __NK_ASSERT_ALWAYS((status & Channel::Status::KHtDescErr) == 0); + } while (status & Channel::Status::KHtDescLoad); // are we still loading desc? + } +#endif + + AsspRegister::Modify32(iBaseAddr + Channel::Ctrl::KHoBase, 0, Channel::Ctrl::KHtSwTrigger); + if(!isIsr) + { + __SPIN_UNLOCK_IRQRESTORE(iLock, irq); + } + +#ifdef _DEBUG_PRINT + Print(); +#endif + } + +void TNeSgChannel::Close() + { + // The lock prevents a channel being closed + // during an ISR. + const TInt irq = __SPIN_LOCK_IRQSAVE(iLock); + DMA_PSL_CHAN_TRACE("Close"); + + // Check that the channel was Idle and Stopped + __NK_ASSERT_ALWAYS(IsIdle()); + __NK_ASSERT_ALWAYS(iTransferCount == 0); + + // Here we clear iController in advance of the PIL + // If we did not do this, then when we release the lock, the ISR + // could observe it as non-null, proceed, but then have the PIL + // clear it mid-isr + iController = NULL; + + __SPIN_UNLOCK_IRQRESTORE(iLock, irq); + } + +#ifdef _DEBUG_PRINT_ISR +void TNeSgChannel::Print() + { + FUNC_LOG; + PRINT(CurrSrcAddr()); + PRINT(CurrDstAddr()); + PRINT(CurrByteCount()); + PRINT(Status()); + PRINT(Config()); + PRINT(CurrLink()); + PRINT(NextLink()); + + Kern::Printf(""); + } +#endif + +void TNeSgChannel::QueuedRequestCountChanged() + { + const TInt qreqs = __e32_atomic_load_acq32(&iQueuedRequests); + DMA_PSL_CHAN_TRACE1("TNE1DmaChannel::QueuedRequestCountChanged() %d", qreqs); + __DMA_ASSERTA(qreqs >= 0); + } + + +TNaviEngineDmac64Sg::TNaviEngineDmac64Sg() +// +// Constructor. +// + : TDmac(KInfo) + { + FUNC_LOG; + for(TInt i = 0; i < Dma64::KChannelCount; i++) + { + // cannot use assignment since internal refernces + // eg. iNullPtr = &iCurHdr will become invalid + new (&iChannels[i]) TNeSgChannel(i); + } + } + + +TInt TNaviEngineDmac64Sg::Create() +// +// Second phase construction. +// + { + FUNC_LOG; + TInt r = TDmac::Create(KInfo); // Base class Create() + if (r == KErrNone) + { + r = Interrupt::Bind(KIntDMAC64_End, IsrEnd, this); + __DMA_ASSERTA(r >= KErrNone); + + r = Interrupt::Enable(KIntDMAC64_End); + __DMA_ASSERTA(r >= KErrNone); + + r = Interrupt::Bind(KIntDMAC64_Err, IsrErr, this); + __DMA_ASSERTA(r >= KErrNone); + + r = Interrupt::Enable(KIntDMAC64_Err); + __DMA_ASSERTA(r >= KErrNone); + } + return r; + } + + +void TNaviEngineDmac64Sg::Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr) +// +// Initiates a (previously constructed) request on a specific channel. +// + { + TDma64Desc* hwDes = HdrToHwDes(aHdr); + + TDmaChannel& mutableChannel = const_cast(aChannel); + TNeSgChannel& channel = static_cast(mutableChannel); + channel.Transfer(hwDes); + } + +// Note for if Pause and Resume is ever made externally +// accessible for this driver. This function has potentially +// undesirable behaviour if it is called while the channel is +// paused. Although any remaining transfers in the linked list +// will be abandoned it will allow the current transfer to +// complete. It would need to be modified to prevent this. +void TNaviEngineDmac64Sg::StopTransfer(const TDmaChannel& aChannel) +// +// Stops a running channel. +// + { + const TInt id = aChannel.PslId(); + + DMA_PSL_CHAN_TRACE_STATIC(aChannel, "StopTransfer"); + +#ifdef _DEBUG_PRINT + iChannels[id].Print(); +#endif + + //This implements the ForcedEnd procdure on page 2-10-82 of NaviEngine TRM + const TUint32 channelBase = iChannels[id].BaseAddr(); + volatile TUint32 channelStatus = NULL; + + + AsspRegister::Write32(channelBase + Channel::Interval::KHo, 0); + FOREVER + { + FOREVER + { + AsspRegister::Modify32(channelBase + Channel::Ctrl::KHoBase, NULL, Channel::Ctrl::KHtSetSuspend); + channelStatus = AsspRegister::Read32(channelBase + Channel::Status::KHoBase); + + if((channelStatus & (Channel::Status::KHtDescWb|Channel::Status::KHtDescLoad)) == 0) + { + //we can leave loop if there is no descriptor load or + //writeback in progress + break; + } + AsspRegister::Modify32(channelBase + Channel::Ctrl::KHoBase, NULL, Channel::Ctrl::KHtClrSuspend); + } + + //Switch back to single transfer + register mode, + //mask completion + end interrupts. + AsspRegister::Modify32(channelBase + Channel::Cfg::KHoBase, + Channel::Cfg::KHtTransMode | Channel::Cfg::KHtLinkMode, + Channel::Cfg::KHtEndMask | Channel::Cfg::KHtCompMask); + + AsspRegister::Modify32(channelBase + Channel::Ctrl::KHoBase, NULL, Channel::Ctrl::KHtClrSuspend); + AsspRegister::Modify32(channelBase + Channel::Ctrl::KHoBase, NULL, Channel::Ctrl::KHtSetSuspend); + + channelStatus = AsspRegister::Read32(channelBase + Channel::Status::KHoBase); + AsspRegister::Modify32(channelBase + Channel::Ctrl::KHoBase, NULL, Channel::Ctrl::KHtClrSuspend); + + if((channelStatus & (Channel::Status::KHtDescWb|Channel::Status::KHtDescLoad)) == 0) + { + break; + } + } + + //WARNING: This step is not mentioned in the forced stop + //procedure. + //We have now broken out of linked mode, and just want to finish + //transfer of the current desc, so switch back to block transfer + //mode and set the software trigger so we can complete. + AsspRegister::Modify32(channelBase + Channel::Cfg::KHoBase, 0, Channel::Cfg::KHtTransMode); + AsspRegister::Modify32(channelBase + Channel::Ctrl::KHoBase, 0, Channel::Ctrl::KHtSwTrigger); + + FOREVER + { + if( + ((channelStatus & (Channel::Status::KHtAct | Channel::Status::KHtRqst)) == 0) || + ((channelStatus & Channel::Status::KHtEnabled) == 0) + ) + { + break; + } + channelStatus = AsspRegister::Read32(channelBase + Channel::Status::KHoBase); + } + + + AsspRegister::Modify32(channelBase + Channel::Ctrl::KHoBase, NULL, Channel::Ctrl::KHtSwReset); + +#ifdef _DEBUG + //we are deliberatly breaking a descriptor chain + //so clear Next Link Address + AsspRegister::Write32(channelBase + Channel::KHoNxtLnkAddr, NULL); +#endif + + TDmaChannel& mutableChannel = const_cast(aChannel); + TNeSgChannel& channel = static_cast(mutableChannel); + + const TInt irq = __SPIN_LOCK_IRQSAVE(channel.iLock); + channel.iTransferCount = 0; + __SPIN_UNLOCK_IRQRESTORE(channel.iLock, irq); + } + +TBool TNaviEngineDmac64Sg::IsIdle(const TDmaChannel& aChannel) +// +// Returns the state of a given channel. +// + { + const TNeSgChannel& channel = static_cast(aChannel); + + __KTRACE_OPT(KDMA, Kern::Printf("TNaviEngineDmac64Sg::IsIdle channel=%d, chanStatus=0x%08x", + channel.PslId(), channel.Status())); + + return channel.IsIdle(); + } + + +TUint TNaviEngineDmac64Sg::MaxTransferLength(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/, + TUint /*aDstFlags*/, TUint32 /*aPslInfo*/) +// +// Returns the maximum transfer size for a given transfer. +// + { + return KDma64MaxTransferBytes; + } + + +TUint TNaviEngineDmac64Sg::AddressAlignMask(TDmaChannel& /*aChannel*/, TUint /*aSrcFlags*/, + TUint /*aDstFlags*/, TUint32 /*aPslInfo*/) +// +// Returns the memory buffer alignment restrictions mask for a given transfer. +// + { + // The 64 bit DMAC does not impose any alignment restriction on + // src and dst buffers, for any channel + return 0x0; + } + + +TInt TNaviEngineDmac64Sg::InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs) +// +// Sets up (from a passed in request) the descriptor with that fragment's +// transfer parameters. +// + { + TDma64Desc* pD = HdrToHwDes(aHdr); + + __KTRACE_OPT(KDMA, Kern::Printf("TNaviEngineDmac64Sg::InitHwDes 0x%08X", pD)); + + // Unaligned descriptor? Bug in generic layer! + __DMA_ASSERTD(IsHwDesAligned(pD)); + pD->Clear(); + + // The DMAC supports write back (ie. marking a descriptor as dirty after + // it's been transferred) + // We disable it here, because the test code (and other clients?) assume + // they may simply requeue a transfer after it has run + pD->iHeader = HwDesHeader::KHtLe | HwDesHeader::KHtLv | HwDesHeader::KHtWbd; + + const TDmaTransferConfig& src = aTransferArgs.iSrcConfig; + const TDmaTransferConfig& dst = aTransferArgs.iDstConfig; + pD->iSrcAddr = (src.iFlags & KDmaPhysAddr) ? src.iAddr : Epoc::LinearToPhysical(src.iAddr); + __DMA_ASSERTD(pD->iSrcAddr != KPhysAddrInvalid); + pD->iDestAddr = (dst.iFlags & KDmaPhysAddr) ? dst.iAddr : Epoc::LinearToPhysical(dst.iAddr); + __DMA_ASSERTD(pD->iDestAddr != KPhysAddrInvalid); + + pD->iTransactionByte = aTransferArgs.iTransferCount; + + __KTRACE_OPT(KDMA, Kern::Printf(" src=0x%08X dest=0x%08X count=%d", + pD->iSrcAddr, pD->iDestAddr, pD->iTransactionByte)); + pD->iConfig = 0; + + // Since this controller only supports memory to memory transfers + // we enable block transfer for every descriptor + pD->iConfig |= Channel::Cfg::KHtTransMode; + + pD->SetSourceDataSize(TDma64Desc::E512Bit); + pD->SetDestDataSize(TDma64Desc::E512Bit); + + return KErrNone; + } + + +TInt TNaviEngineDmac64Sg::UpdateHwDes(const SDmaDesHdr& aHdr, TUint32 aSrcAddr, TUint32 aDstAddr, + TUint aTransferCount, TUint32 aPslRequestInfo) +// +// Updates (from the passed in arguments) fields of the descriptor. This +// function is called by the PIL in ISR context. +// + { + TDma64Desc* pD = HdrToHwDes(aHdr); + + __KTRACE_OPT(KDMA, Kern::Printf("TNaviEngineDmac64Sg::UpdateHwDes 0x%08X", pD)); + + // Unaligned descriptor? Bug in generic layer! + __DMA_ASSERTD(IsHwDesAligned(pD)); + + // Addresses passed into this function are always physical ones. + if (aSrcAddr != KPhysAddrInvalid) + { + __KTRACE_OPT(KDMA, Kern::Printf(" Changing src addr, old: 0x%08X new: 0x%08X", + pD->iSrcAddr, aSrcAddr)); + pD->iSrcAddr = aSrcAddr; + } + if (aDstAddr != KPhysAddrInvalid) + { + __KTRACE_OPT(KDMA, Kern::Printf(" Changing dst addr, old: 0x%08X new: 0x%08X", + pD->iDestAddr, aDstAddr)); + pD->iDestAddr = aDstAddr; + } + if (aTransferCount != 0) + { + __KTRACE_OPT(KDMA, Kern::Printf(" Changing xfer count, old: %d new: %d", + pD->iTransactionByte, aTransferCount)); + pD->iTransactionByte = aTransferCount; + } + if (aPslRequestInfo != 0) + { + __KTRACE_OPT(KDMA, Kern::Printf(" aPslRequestInfo specified (0x%08X) but ignored", + aPslRequestInfo)); + } + + __KTRACE_OPT(KDMA, Kern::Printf(" src=0x%08X dest=0x%08X count=%d", + pD->iSrcAddr, pD->iDestAddr, pD->iTransactionByte)); + + return KErrNone; + } + +/** +Like ChainHwDes, but does not suppress interrupts in the descriptor +being appended to. +*/ +void TNaviEngineDmac64Sg::JoinHwDes(TDma64Desc& aHwDes, const TDma64Desc& aNextHwDes) + { + // Unaligned descriptor? Bug in generic layer! + __DMA_ASSERTD(IsHwDesAligned(&aHwDes) && IsHwDesAligned(&aNextHwDes)); + + aHwDes.iHeader &= ~(HwDesHeader::KHtLe); + __NK_ASSERT_DEBUG(aHwDes.iNextLink == NULL); + aHwDes.iNextLink = Epoc::LinearToPhysical(reinterpret_cast(&aNextHwDes)); + __DMA_ASSERTD(aHwDes.iNextLink != KPhysAddrInvalid); + } + +void TNaviEngineDmac64Sg::ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr) +// +// Chains hardware descriptors together by setting the next pointer of the original descriptor +// to the physical address of the descriptor to be chained. +// + { + TDma64Desc* pD = HdrToHwDes(aHdr); + TDma64Desc* pN = HdrToHwDes(aNextHdr); + + __KTRACE_OPT(KDMA, Kern::Printf("TNaviEngineDmac64Sg::ChainHwDes des=0x%08X next des=0x%08X", pD, pN)); + + JoinHwDes(*pD, *pN); + + //only the last link in the chain should produce an interrupt or + //set the "transfer complete" bit + pD->iConfig |= (Channel::Cfg::KHtEndMask|Channel::Cfg::KHtCompMask); + } + + +void TNaviEngineDmac64Sg::AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr, + const SDmaDesHdr& aNewHdr) +// +// Appends a descriptor to the chain while the channel is running. +// + { + const TUint32 i = static_cast(aChannel.PslId()); + + TDma64Desc* pL = HdrToHwDes(aLastHdr); + TDma64Desc* pN = HdrToHwDes(aNewHdr); + + __KTRACE_OPT(KDMA, Kern::Printf("TNaviEngineDmac64Sg::AppendHwDes channel=%d last des=0x%08X new des=0x%08X", + i, pL, pN)); + + TNeSgChannel& channel(iChannels[i]); + + channel.Pause(); + +#ifdef _DEBUG_PRINT + __KTRACE_OPT(KDMA, Kern::Printf("Last descriptor:")); + pL->Print(); + __KTRACE_OPT(KDMA, Kern::Printf("Next descriptor:")); + pN->Print(); + iChannels[i].Print(); +#endif + //Check we are really appending on to the end of a chain + __NK_ASSERT_DEBUG(pL->iNextLink == 0); + + if(channel.NextLink()) + { + //Simple case, the dmac is still working through the desriptor + //chain - just add new link to the end. + JoinHwDes(*pL, *pN); + + const TInt irq = __SPIN_LOCK_IRQSAVE(channel.iLock); + channel.iTransferCount++; + __SPIN_UNLOCK_IRQRESTORE(channel.iLock, irq); + + DMA_PSL_CHAN_TRACE_STATIC1(aChannel, "requests chained iTransferCount %d", channel.iTransferCount); + channel.Resume(); + } + else + { + // If the next link register is not set, then the controller is + // either on last descriptor or has completed (though PIL not yet aware) + channel.Resume(); + + // Wait till the channel is idle so that we don't disrupt the + // transfer of the final descriptor, if it's still running. + while(!channel.IsIdle()) + { + } + Transfer(aChannel, aNewHdr); + } + +#ifdef _DEBUG_PRINT + __KTRACE_OPT(KDMA, Kern::Printf("Last descriptor:")); + pL->Print(); + iChannels[i].Print(); +#endif + __KTRACE_OPT(KDMA, Kern::Printf("iHeader |= HwDesHeader::KHtLe; + + //Allow this descriptor to raise completion interrupts again. + pD->iConfig &= ~(Channel::Cfg::KHtEndMask|Channel::Cfg::KHtCompMask); + + pD->iNextLink = 0; + } + + +void TNaviEngineDmac64Sg::IsrEnd(TAny* aThis) +// +// This ISR reads the interrupt identification and calls back into the base class +// interrupt service handler with the channel identifier and an indication whether the +// transfer completed correctly or with an error. +// + { + FUNC_LOG; + + TNaviEngineDmac64Sg& me = *static_cast(aThis); + + const TUint32 channelTcStates = AsspRegister::Read32(KHwDMAC64Base + Cmn::KHoTc); + const TUint32 channelErrStates = AsspRegister::Read32(KHwDMAC64Base + Cmn::KHoErr); + + TNeSgChannel* channel = NULL; + for (TInt i=0; iiLock); + + if(channel->iController == NULL) + { + // skip closed channel + __SPIN_UNLOCK_IRQRESTORE(channel->iLock, irq); + continue; + } + + // If error then it could have been raised by any of the + // previous requests - they must all be completed with + // an error status + if(error) + { + // Reset the channel and iTransferCount before + // calling HandleIsr since each one could lead + // to a new transfer + TUint32 clearMask = Channel::Ctrl::KHtSwReset; + AsspRegister::Modify32(channel->BaseAddr() + Channel::Ctrl::KHoBase, 0, clearMask); + + const TInt badTransfers = channel->iTransferCount; + channel->iTransferCount = 0; + for(TInt j=0; j < badTransfers; j++) + { + HandleIsr(*channel, EDmaCallbackRequestCompletion, EFalse); + } + __SPIN_UNLOCK_IRQRESTORE(channel->iLock, irq); + continue; + } + + if((channel->iTransferCount > 0) && channel->IsIdle()) + { + TInt missedCount = channel->iTransferCount; + if(transferComplete) + { + // If a transfer has completed normally + // then allow that to be handled in the next block + missedCount--; + } + DMA_PSL_CHAN_TRACE_STATIC1((*channel), "clearing %d missed irqs", missedCount); + for(TInt j=0; j < missedCount; j++) + { + HandleIsr(*channel, EDmaCallbackRequestCompletion, ETrue); + } + channel->iTransferCount -= missedCount; + } + + if (transferComplete) + { +#ifdef _DEBUG_PRINT_ISR + channel->Print(); +#endif + { + using namespace Channel::Ctrl; + TUint32 setMask = KHtClrTc | KHtClrEnd | KHtSwTrigger; + AsspRegister::Modify32(channel->BaseAddr() + KHoBase, 0, setMask); + } + + // Only signal the PIL if iTransferCount is not 0. + // StopTransfer could have reset the count. + if(channel->iTransferCount > 0) + { + HandleIsr(*channel, EDmaCallbackRequestCompletion, ETrue); + channel->iTransferCount--; + } + + } + __SPIN_UNLOCK_IRQRESTORE(channel->iLock, irq); + } + } + + +void TNaviEngineDmac64Sg::IsrErr(TAny* aThis) +// +// This ISR reads the interrupt identification and calls back into the base class +// interrupt service handler with the channel identifier and an indication whether the +// transfer completed correctly or with an error. +// + { + FUNC_LOG; + IsrEnd(aThis); // IsrEnd will report the error + } + +inline TDma64Desc* TNaviEngineDmac64Sg::HdrToHwDes(const SDmaDesHdr& aHdr) +// +// Changes return type of base class call. +// + { + return static_cast(TDmac::HdrToHwDes(aHdr)); + } +// +// DLL Exported Function +// + +DECLARE_STANDARD_EXTENSION() +// +// Creates and initializes a new DMA controller object on the kernel heap. +// + { + __KTRACE_OPT2(KBOOT, KDMA, Kern::Printf("Starting DMA Extension")); + + TInt r = DmaChannelMgr::Initialise(); + if(r!=KErrNone) + { + return r; + } + + r = Controller64.Create(); + if(r!=KErrNone) + { + return r; + } + + return Controller.Create(); + } diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/eabi/ei2su.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/eabi/ei2su.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,34 @@ +EXPORTS + _ZN3I2s10DisableDMAEii @ 1 NONAME + _ZN3I2s10EnableFIFOEiNS_14TI2sFramePhaseEi @ 2 NONAME + _ZN3I2s11DisableFIFOEiNS_14TI2sFramePhaseEi @ 3 NONAME + _ZN3I2s12IsDMAEnabledEiRi @ 4 NONAME + _ZN3I2s13IsFIFOEnabledEiNS_14TI2sFramePhaseERi @ 5 NONAME + _ZN3I2s13ReadFIFOLevelEiNS_14TI2sFramePhaseENS_13TI2sDirectionERi @ 6 NONAME + _ZN3I2s14GetDelayCyclesEiNS_14TI2sFramePhaseERi @ 7 NONAME + _ZN3I2s14GetFrameFormatEiRiS0_ @ 8 NONAME + _ZN3I2s14SetDelayCyclesEiNS_14TI2sFramePhaseEi @ 9 NONAME + _ZN3I2s15GetSampleLengthEiNS_14TI2sFramePhaseERi @ 10 NONAME + _ZN3I2s15GetSamplingRateEiRi @ 11 NONAME + _ZN3I2s15SetSampleLengthEiNS_14TI2sFramePhaseENS_16TI2sSampleLengthE @ 12 NONAME + _ZN3I2s15SetSamplingRateEiNS_16TI2sSamplingRateE @ 13 NONAME + _ZN3I2s16SetFIFOThresholdEiNS_14TI2sFramePhaseENS_13TI2sDirectionEi @ 14 NONAME + _ZN3I2s18ConfigureInterfaceEiP5TDes8 @ 15 NONAME + _ZN3I2s18ReadFIFOModeStatusEiNS_14TI2sFramePhaseERi @ 16 NONAME + _ZN3I2s19ReadReceiveRegisterEiNS_14TI2sFramePhaseERi @ 17 NONAME + _ZN3I2s20EnableFIFOInterruptsEiNS_14TI2sFramePhaseEi @ 18 NONAME + _ZN3I2s20ReadTransmitRegisterEiNS_14TI2sFramePhaseERi @ 19 NONAME + _ZN3I2s21DisableFIFOInterruptsEiNS_14TI2sFramePhaseEi @ 20 NONAME + _ZN3I2s21WriteTransmitRegisterEiNS_14TI2sFramePhaseEi @ 21 NONAME + _ZN3I2s22IsFIFOInterruptEnabledEiNS_14TI2sFramePhaseERi @ 22 NONAME + _ZN3I2s22ReadRegisterModeStatusEiNS_14TI2sFramePhaseERi @ 23 NONAME + _ZN3I2s23SetFrameLengthAndFormatEiNS_15TI2sFrameLengthEi @ 24 NONAME + _ZN3I2s24EnableRegisterInterruptsEiNS_14TI2sFramePhaseEi @ 25 NONAME + _ZN3I2s25DisableRegisterInterruptsEiNS_14TI2sFramePhaseEi @ 26 NONAME + _ZN3I2s25GetInterfaceConfigurationEiR5TDes8 @ 27 NONAME + _ZN3I2s26IsRegisterInterruptEnabledEiNS_14TI2sFramePhaseERi @ 28 NONAME + _ZN3I2s4StopEii @ 29 NONAME + _ZN3I2s5StartEii @ 30 NONAME + _ZN3I2s9EnableDMAEii @ 31 NONAME + _ZN3I2s9IsStartedEiNS_13TI2sDirectionERi @ 32 NONAME + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/eabi/kanaviengine.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/eabi/kanaviengine.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,34 @@ +EXPORTS + _Z14AsicInitialisev @ 1 NONAME + _ZN11TNaviEngine10SetRtcDataEj @ 2 NONAME + _ZN11TNaviEngine12CpuVersionIdEv @ 3 NONAME + _ZN11TNaviEngine12VideoRamPhysEv @ 4 NONAME + _ZN11TNaviEngine13DebugPortAddrEv @ 5 NONAME + _ZN11TNaviEngine13StartupReasonEv @ 6 NONAME + _ZN11TNaviEngine19ProcessorPeriodInPsEv @ 7 NONAME + _ZN11TNaviEngine20BootWaitMilliSecondsEi @ 8 NONAME + _ZTV14NaviEngineAssp @ 9 NONAME + _ZN11TNaviEngine7RtcDataEv @ 10 NONAME + _ZN12AsspRegister6Read64Em @ 11 NONAME + _ZN12AsspRegister7Modify8Emhh @ 12 NONAME + _ZN12AsspRegister7Write64Emy @ 13 NONAME + _ZN12AsspRegister8Modify16Emtt @ 14 NONAME + _ZN12AsspRegister8Modify32Emmm @ 15 NONAME + _ZN12AsspRegister8Modify64Emyy @ 16 NONAME + _ZN14NaviEngineAssp11DebugOutputEj @ 17 NONAME + _ZN14NaviEngineAssp12MsTickPeriodEv @ 18 NONAME + _ZN14NaviEngineAssp13StartupReasonEv @ 19 NONAME + _ZN14NaviEngineAssp19NanoWaitCalibrationEv @ 20 NONAME + _ZN14NaviEngineAssp27SystemTimeInSecondsFrom2000ERi @ 21 NONAME + _ZN14NaviEngineAssp30SetSystemTimeInSecondsFrom2000Ei @ 22 NONAME + _ZN14NaviEngineAssp5Init1Ev @ 23 NONAME + _ZN14NaviEngineAssp5Init3Ev @ 24 NONAME + _ZN14NaviEngineAsspC2Ev @ 25 NONAME + _ZN9Interrupt11SetPriorityEii @ 26 NONAME + _ZN9Interrupt4BindEiPFvPvES0_ @ 27 NONAME + _ZN9Interrupt5ClearEi @ 28 NONAME + _ZN9Interrupt6EnableEi @ 29 NONAME + _ZN9Interrupt6UnbindEi @ 30 NONAME + _ZN9Interrupt7DisableEi @ 31 NONAME + _ZTI14NaviEngineAssp @ 32 NONAME + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/eabi/pciu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/eabi/pciu.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,35 @@ +EXPORTS + _ZN10TAddrSpace4SizeEv @ 1 NONAME + _ZN12TConfigSpace5Read8Em @ 2 NONAME + _ZN12TConfigSpace6Read16Em @ 3 NONAME + _ZN12TConfigSpace6Read32Em @ 4 NONAME + _ZN12TConfigSpace6Write8Emh @ 5 NONAME + _ZN12TConfigSpace7Modify8Emhh @ 6 NONAME + _ZN12TConfigSpace7Write16Emt @ 7 NONAME + _ZN12TConfigSpace7Write32Emm @ 8 NONAME + _ZN12TConfigSpace8Modify16Emtt @ 9 NONAME + _ZN12TConfigSpace8Modify32Emmm @ 10 NONAME + _ZN12TPciFunction14GetConfigSpaceEv @ 11 NONAME + _ZN12TPciFunction14GetMemorySpaceEi @ 12 NONAME + _ZN3Pci11CreateChunkEiRP12DPlatChunkHwijRm @ 13 NONAME + _ZN3Pci11CreateChunkEiRP6DChunkR16TChunkCreateInfojjRm @ 14 NONAME + _ZN3Pci11RemoveChunkEiP12DPlatChunkHw @ 15 NONAME + _ZN3Pci13CreateMappingEimiRm @ 16 NONAME + _ZN3Pci13GetPciAddressEiRm @ 17 NONAME + _ZN3Pci13RemoveMappingEim @ 18 NONAME + _ZN3Pci14GetConfigSpaceEi @ 19 NONAME + _ZN3Pci14GetMemorySpaceEii @ 20 NONAME + _ZN3Pci18GetPhysicalAddressEiRm @ 21 NONAME + _ZN3Pci20ChunkCleanupCallbackEP13TChunkCleanup @ 22 NONAME + _ZN3Pci5ProbeER6RArrayIiEtt @ 23 NONAME + _ZTI10DPciBridge @ 24 NONAME + _ZTI12TConfigSpace @ 25 NONAME + _ZTI12TMemorySpace @ 26 NONAME + _ZTI20DNaviEnginePciBridge @ 27 NONAME + _ZTI23TNaviEngineChunkCleanup @ 28 NONAME + _ZTV10DPciBridge @ 29 NONAME + _ZTV12TConfigSpace @ 30 NONAME + _ZTV12TMemorySpace @ 31 NONAME + _ZTV20DNaviEnginePciBridge @ 32 NONAME + _ZTV23TNaviEngineChunkCleanup @ 33 NONAME + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/gpio.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/gpio.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,822 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\gpio.cpp +* NaviEngine implementation of the MHA GPIO class +* +*/ + + + +#include +#include + +const TInt32 KHwGpioPinMax = 31; +const TInt32 KHwGpioEdgeRising = 0x0; +const TInt32 KHwGpioEdgeFalling = 0x1; +const TInt32 KHwGpioEdgeBoth = 0x2; +const TInt32 KHwGpioLevelLow = 0x3; +const TInt32 KHwGpioLevelHigh = 0x4; + +const TInt32 KGpioDebounceInterval = 1; // (in ticks) +const TInt32 KGpioMaxRetries = 8; + +class GpioPin + { +public: + GPIO::TGpioMode iMode; + TGpioIsr iIsr; + TAny * iPtr; + TInt iDebounce; + }; + +static GpioPin GpioPins[KHwGpioPinMax+1]; +static TInt32 GpioInterruptId; +#ifdef __SMP__ +const TInt32 KGpioLockOrder = TSpinLock::EOrderGenericIrqLow2; +static TSpinLock GpioSpinLock(KGpioLockOrder); +#endif + +inline TInt GpioLock(); +inline void GpioUnlock(TInt irq); + +/** +Calculate 16-bit device pin Id from 32-bit pin Id. Use DeviceId() to +get device Id. +@param aId 32-bit pin Id +@return 16-bit device specific pin Id +*/ +static inline TUint16 DevicePinId(TInt aId) + {return static_cast(aId & 0x0000FFFF);} + + +//Commented out to satisfy compiler(as method is not used in the code) but can +//be usefull later +/** +Calculate and return GPIO device Id(either SOC or one of the extenders) +defined in TGpioBaseId from the 32-bit pin Id +@param aId 32-bit pin Id +@return + - EInternalId SOC GPIO + - EExtender0-15 GPIO extenders from 0-15 + +static inline GPIO::TGpioBaseId ExtenderId(TInt aId) + {return static_cast((aId & 0xFFFF0000));} +*/ + +//Commented out to satisfy compiler(as method is not used in the code) but can +//be usefull later +/** +Generate 32-bit pin Id from the device Id and device specific 16-bit +pin Id. +@param aExtenderId Device Id is defined in TGpioBaseId +@param aPinId 16-bit device pin Id +return 32-bit pin Id + +static inline TInt Id(GPIO::TGpioBaseId aExtenderId, TUint16 aPinId) + {return static_cast(aExtenderId |aPinId);} +*/ + +//Commented out to satisfy compiler(as method is not used in the code) but can +//be usefull later +/** +Find index in extender GPIO device table. +@param aExtenderId Extender Id is defined in TGpioBaseId +@return singned 32-bit integer index device, possible value + from 0 to 15 + +static TInt DeviceIndex(GPIO::TGpioBaseId aExtenderId) + { + TUint16 val = (TUint16)((aExtenderId & 0xFFFF0000) >> 16); + if(val == 0) return GPIO::EInternalId; + + //The algorithm steps througth the value until first non-zero bit is + //found. + // + TInt index = 0; + if(val & 0xFF00) {index = 8; val = val >> 8;} // 2 x 8-bits + if(val & 0x00F0) {index += 4; val = val >> 4;} // 2 x 4-bits + if(val & 0x000C) {index += 2; val = val >> 2;} // 2 x 2 bits + if(val & 0x0002) {index += 1; val = val >> 1;} // 2 x 1 bits + + return index; + } +*/ + +//Commented out to satisfy compiler(as method is not used in the code) but can +//be usefull later +/** +Find index in extender GPIO device table. +@param aId 32-bit GPIO pin Id +@return singned 32-bit integer index device, possible value + from 0 to 15 + +static TInt DeviceIndex(TInt aId){return DeviceIndex(ExtenderId(aId));} +*/ + + + +/** +GPIO interrupt handler +Takes a generic argument (TAny*) +*/ +void GpioIsrDispatch(TAny *aPtr) + { + GpioPin *pins = (GpioPin *)aPtr; + TInt irq = GpioLock(); + TUint32 interrupt = AsspRegister::Read32(KHwRwGpio_Int); + TUint32 enabled = AsspRegister::Read32(KHwRwGpio_Int_Enable); + TUint32 masked = interrupt & enabled; + for (TInt i = 0; i <= KHwGpioPinMax; i++) + { + if ((masked & 0x1) && (pins[i].iIsr != NULL)) + { + (*pins[i].iIsr)(pins[i].iPtr); + } + masked >>= 1; + } + Interrupt::Clear(GpioInterruptId); + GpioUnlock(irq); + } + +#include "gpio.inl" + +// +// work out debounced state +// +TInt GetDebouncedState(TInt aId, TUint32 &aVal) + { + + TUint16 pinId = DevicePinId(aId); + TInt debounceCount = GpioPins[pinId].iDebounce/KGpioDebounceInterval; + TInt count = 0; + TInt retries = debounceCount*KGpioMaxRetries; + TUint lastState = AsspRegister::Read32(KHwRoGpio_Port_Value); + TUint state = lastState; + + for (count = 0; count < debounceCount && retries > 0; count ++) + { + NKern::Sleep(KGpioDebounceInterval); + state = AsspRegister::Read32(KHwRoGpio_Port_Value); + + if ((state & 1< KHwGpioPinMax) + { + return KErrArgument; + } + + __e32_atomic_store_rel32(&GpioPins[pinId].iMode, aMode); + return KErrNone; + } + +EXPORT_C TInt GPIO::GetPinMode + ( + TInt aId, + TGpioMode & aMode + ) + { + TUint16 pinId = DevicePinId(aId); + // the chip doesn't support modes, so just return what we stored earlier + if (pinId > KHwGpioPinMax) + { + return KErrArgument; + } + aMode = (TGpioMode) __e32_atomic_load_acq32(&GpioPins[pinId].iMode); + return KErrNone; + } + +EXPORT_C TInt GPIO::SetPinDirection + ( + TInt aId, + TGpioDirection aDirection + ) + { + TUint16 pinId = DevicePinId(aId); + // tristate not supported + if (pinId > KHwGpioPinMax || aDirection == ETriStated) + { + return KErrArgument; + } + // port enabled means output, disabled means input + if (aDirection == EInput) + { + AsspRegister::Write32(KHwWoGpio_Port_Control_Disable, 1< KHwGpioPinMax) + { + return KErrArgument; + } + // port enabled means output, disabled means input + TUint enabled = AsspRegister::Read32(KHwRwGpio_Port_Control_Enable); + if (enabled & 1< KHwGpioPinMax) + { + return KErrArgument; + } + return KErrNotSupported; + } + +EXPORT_C TInt GPIO::GetPinBias + ( + TInt aId, + TGpioBias& /*aBias*/ + ) + { + TUint16 pinId = DevicePinId(aId); + // pin bias not supported + if (pinId > KHwGpioPinMax) + { + return KErrArgument; + } + return KErrNotSupported; + } + +EXPORT_C TInt GPIO::SetPinIdleConfigurationAndState + ( + TInt aId, + TInt /*aConf*/ + ) + { + TUint16 pinId = DevicePinId(aId); + // pin idle configuration and state not supported + if (pinId > KHwGpioPinMax) + { + return KErrArgument; + } + return KErrNotSupported; + } + +EXPORT_C TInt GPIO::GetPinIdleConfigurationAndState + ( + TInt aId, + TInt & /*aBias*/ + ) + { + TUint16 pinId = DevicePinId(aId); + // pin idle configuration and state not supported + if (pinId > KHwGpioPinMax) + { + return KErrArgument; + } + return KErrNotSupported; + } + +EXPORT_C TInt GPIO::BindInterrupt + ( + TInt aId, + TGpioIsr aIsr, + TAny * aPtr + ) + { + TUint16 pinId = DevicePinId(aId); + if (pinId > KHwGpioPinMax || aIsr == NULL) + { + return KErrArgument; + } + TInt irq = GpioLock(); + if (GpioPins[pinId].iIsr != NULL) + { + GpioUnlock(irq); + // already bound + return KErrInUse; + } + GpioPins[pinId].iIsr = aIsr; + GpioPins[pinId].iPtr = aPtr; + GpioUnlock(irq); + return KErrNone; + } + +EXPORT_C TInt GPIO::UnbindInterrupt + ( + TInt aId + ) + { + TUint16 pinId = DevicePinId(aId); + if (pinId > KHwGpioPinMax) + { + return KErrArgument; + } + TInt irq = GpioLock(); + if (GpioPins[pinId].iIsr == NULL) + { + GpioUnlock(irq); + // nothing bound + return KErrGeneral; + } + GpioPins[pinId].iIsr = NULL; + GpioPins[pinId].iPtr = NULL; + GpioUnlock(irq); + return KErrNone; + } + +EXPORT_C TInt GPIO::EnableInterrupt + ( + TInt aId + ) + { + TUint16 pinId = DevicePinId(aId); + if (pinId > KHwGpioPinMax) + { + return KErrArgument; + } + TInt irq = GpioLock(); + if (GpioPins[pinId].iIsr == NULL) + { + GpioUnlock(irq); + // nothing bound + return KErrGeneral; + } + + // hold value so it can be read after triggering + TUint32 held = AsspRegister::Read32(KHwRwGpio_Int_Hold); + AsspRegister::Write32(KHwRwGpio_Int_Hold, held | 1< KHwGpioPinMax) + { + return KErrArgument; + } + TInt irq = GpioLock(); + if (GpioPins[pinId].iIsr == NULL) + { + GpioUnlock(irq); + // nothing bound + return KErrGeneral; + } + // disable interrupt + AsspRegister::Write32(KHwWoGpio_Int_Disable, 1< KHwGpioPinMax) + { + return KErrArgument; + } + TInt irq = GpioLock(); + if (GpioPins[pinId].iIsr == NULL) + { + GpioUnlock(irq); + // nothing bound + return KErrGeneral; + } + aEnable = AsspRegister::Read32(KHwRwGpio_Int_Enable) & (1< KHwGpioPinMax) + { + return KErrArgument; + } + // clear pin interrupt status + AsspRegister::Write32(KHwRwGpio_Int, 1< KHwGpioPinMax) + { + return KErrArgument; + } + TInt irq = GpioLock(); + aActive = AsspRegister::Read32(KHwRwGpio_Int_Enable) & AsspRegister::Read32(KHwRwGpio_Int) & (1< KHwGpioPinMax) + { + return KErrArgument; + } + aActive = AsspRegister::Read32(KHwRwGpio_Int) & (1< KHwGpioPinMax) + { + return KErrArgument; + } + TUint modeRegister = KHwRwGpio_Int_Mode0 + ((pinId >> 3) << 2); + TUint modeShift = pinId & 0x7; + TUint mode; + switch (aTrigger) + { + case ELevelLow: + mode = KHwGpioLevelLow; + break; + case ELevelHigh: + mode = KHwGpioLevelHigh; + break; + case EEdgeFalling: + mode = KHwGpioEdgeFalling; + break; + case EEdgeRising: + mode = KHwGpioEdgeRising; + break; + case EEdgeBoth: + mode = KHwGpioEdgeBoth; + break; + default: + return KErrArgument; + } + + TInt irq = GpioLock(); + TUint currentMode = AsspRegister::Read32(modeRegister) & !(0xf << modeShift); + AsspRegister::Write32(modeRegister, (mode << modeShift) | currentMode); + GpioUnlock(irq); + return KErrNone; + } + +EXPORT_C TInt GPIO::EnableWakeup + ( + TInt aId + ) + { + TUint16 pinId = DevicePinId(aId); + // wakeup not supported + if (pinId > KHwGpioPinMax) + { + return KErrArgument; + } + return KErrNotSupported; + } + +EXPORT_C TInt GPIO::DisableWakeup + ( + TInt aId + ) + { + TUint16 pinId = DevicePinId(aId); + // wakeup not supported + if (pinId > KHwGpioPinMax) + { + return KErrArgument; + } + return KErrNotSupported; + } + +EXPORT_C TInt GPIO::IsWakeupEnabled + ( + TInt aId, + TBool & /*aEnable*/ + ) + { + TUint16 pinId = DevicePinId(aId); + // wakeup not supported + if (pinId > KHwGpioPinMax) + { + return KErrArgument; + } + return KErrNotSupported; + } + +EXPORT_C TInt GPIO::SetWakeupTrigger + ( + TInt aId, + TGpioDetectionTrigger /*aTrigger*/ + ) + { + TUint16 pinId = DevicePinId(aId); + // wakeup not supported + if (pinId > KHwGpioPinMax) + { + return KErrArgument; + } + return KErrNotSupported; + } + +EXPORT_C TInt GPIO::SetDebounceTime + ( + TInt aId, + TInt aTime + ) + { + TUint16 pinId = DevicePinId(aId); + if (pinId > KHwGpioPinMax) + { + return KErrArgument; + } + TInt irq = GpioLock(); + GpioPins[pinId].iDebounce = NKern::TimerTicks(aTime/1000); + GpioUnlock(irq); + return KErrNone; + } + +EXPORT_C TInt GPIO::GetDebounceTime + ( + TInt aId, + TInt & aTime + ) + { + TUint16 pinId = DevicePinId(aId); + if (pinId > KHwGpioPinMax) + { + return KErrArgument; + } + TInt irq = GpioLock(); + aTime = (GpioPins[pinId].iDebounce*1000)/NKern::TimerTicks(1); + GpioUnlock(irq); + return KErrNone; + } + +EXPORT_C TInt GPIO::GetInputState + ( + TInt aId, + TGpioState & aState + ) + { + TUint16 pinId = DevicePinId(aId); + if (pinId > KHwGpioPinMax) + { + return KErrArgument; + } + // check it is enabled and is an input port + TInt irq = GpioLock(); + if (GpioPins[pinId].iMode != EEnabled || (AsspRegister::Read32(KHwRwGpio_Port_Control_Enable) & 1< KHwGpioPinMax) + { + return KErrArgument; + } + TInt irq = GpioLock(); + if (GpioPins[pinId].iMode != EEnabled) + { + GpioUnlock(irq); + return KErrGeneral; + } + TUint outputReg, value; + if (pinId >= 16) + { + outputReg = KHwWoGpio_Port_Set_Clear_Hi; + pinId = pinId - 16; + } + else + { + outputReg = KHwWoGpio_Port_Set_Clear_Lo; + } + if (aState == EHigh) + { + value = 1 << pinId; // LSW - set.. + } + else + { + value = 1 << (pinId + 16); // MSW - clear.. + } + + AsspRegister::Write32(outputReg, value); + GpioUnlock(irq); + return KErrNone; + } + +EXPORT_C TInt GPIO::GetOutputState + ( + TInt aId, + TGpioState & aState + ) + { + TUint16 pinId = DevicePinId(aId); + if (pinId > KHwGpioPinMax) + { + return KErrArgument; + } + // atomic - no lock required + TUint32 state = AsspRegister::Read32(KHwRoGpio_Port_Value); + if(state & (1< KHwGpioPinMax) + { + return KErrArgument; + } + return KErrNotSupported; + } + +EXPORT_C TInt GPIO::SetOutputState + ( + TInt aId, + TGpioState /*aState*/, + TGpioCallback * /*aCb*/ + ) + { + TUint16 pinId = DevicePinId(aId); + // asynch calls not supported + if (pinId > KHwGpioPinMax) + { + return KErrArgument; + } + return KErrNotSupported; + } + +#ifndef __USE_GPIO_STATIC_EXTENSION__ +EXPORT_C TInt GPIO::StaticExtension + ( + TInt aId, + TInt /*aCmd*/, + TAny * /*aArg1*/, + TAny * /*aArg2*/ + ) + { + TUint16 pinId = DevicePinId(aId); + // static extensions not supported + if (pinId > KHwGpioPinMax) + { + return KErrArgument; + } + return KErrNotSupported; + } +#endif + +DECLARE_STANDARD_EXTENSION() + { + TInt irq = GpioLock(); + // initialise GPIO pins array + for (TInt32 i = 0; i <= KHwGpioPinMax; i++) + { + GpioPins[i].iMode = GPIO::EIdle; + GpioPins[i].iIsr = NULL; + GpioPins[i].iPtr = NULL; + GpioPins[i].iDebounce = 0; + } + GpioUnlock(irq); + TInt r = Interrupt::Bind(KIntIdGpio, GpioIsrDispatch, &GpioPins[0]); + if (r < 0) + { + return r; + } + GpioInterruptId = r; + Interrupt::Clear(GpioInterruptId); + Interrupt::Enable(GpioInterruptId); + return KErrNone; + } diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/gpio.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/gpio.inl Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\gpio.inl +* NaviEngine implementation of the MHA GPIO class +* +*/ + + + +inline TInt GpioLock() + { + return __SPIN_LOCK_IRQSAVE(GpioSpinLock); + } + +inline void GpioUnlock(TInt irq) + { + __SPIN_UNLOCK_IRQRESTORE(GpioSpinLock, irq); + } + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/hcr/hcr_psl_config_assp.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/hcr/hcr_psl_config_assp.inl Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,198 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file is part of the NE1_TB Variant Base Port +* Hardware Configuration Respoitory compiled repository in-line cpp. +* +*/ + + +/** +@file hcr_psl_config_assp.inl +File provides setting definitions for the ASSP setting values applicable to the +NEC NaviEngine base port. These definitions also contain the setting value where +the setting value is no larger than a 32-bit integer. The values for +larger settings can be found in the peer file hcr_psl_config_assp_lsd.inl. + +@internalTechnology +*/ + + +#ifndef HCR_PSL_CONFIG_ASSP_INL +#define HCR_PSL_CONFIG_ASSP_INL + + +// SSettingC gSettingsList[] = +// { +// + +/** +HCR Setting values for ASSP Hardware Block base virtual addresses for FMM and MMM. +*/ + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_Uart0}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseUart0)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_Uart1}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseUart1)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_Uart2}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseUart2)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_MPCorePrivate}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseMPCorePrivate)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_SCU}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseSCU)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_IntIf}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseIntIf)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_IntDist}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseGlobalIntDist)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_Timers}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwTimersBase)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_Watchdog}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwWatchdog)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_SystemCtrl}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwSystemCtrlBase)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_Display}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwDisplayBase)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_I2C}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseI2C)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_I2S0}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseI2S0)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_I2S1}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseI2S1)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_I2S2}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseI2S2)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_I2S3}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseI2S3)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_FPGA}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwFPGABase)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_CDDisp}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseUart0)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_TSP}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseUart0)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_SPDIF}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwSPDIFBase)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_CSI0}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseCSI0)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_CSI1}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseCSI1)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_SDCtrl}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseSDCtrl)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_KDMACExBus}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KDMACExBusBase)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_KDMAC32}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KDMAC32Base)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_Ethernet}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseEthernet)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_GPIOBase}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwGPIOBase)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_PciBase}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwPciBase)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_PciBridgeExtern}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwPciBridgeExtern)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_PciBridgeUsb}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwPciBridgeUsb)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwBase_UsbHWindow}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwUsbHWindow)} } }, + +/* +HCR Setting values for ASSP Physical addresses. +*/ + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_BaseMPcorePrivate}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwBaseMPcorePrivatePhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_DDR2RamBase}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwDDR2RamBasePhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_PCI}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwPCIPhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_Internal}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwInternal)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_AXI64IC2}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwAXI64IC2Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_SATA}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwSATAPhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_AXI64DMAC}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwAXI64DMACPhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_Video}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwVideoPhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_Disp}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwDispPhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_SGX}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwSGXPhys)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_CFWindow2}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwCFWindow2Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_CFWindow1}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwCFWindow1Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_CFWindow0}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwCFWindow0Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_ATA6CS1}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwATA6_CS1Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_ATA6CS0}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwATA6_CS0Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_USBH}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwUSBHPhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_AHB32PCIUSB}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwAHB32PCI_USBPhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_AHB32PCIExt}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwAHB32PCI_ExtPhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_DDR2Reg}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwDDR2RegPhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_AHB0DMAC4}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwAHB0DMAC4Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_AHB0DMAC3}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwAHB0DMAC3Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_AHB0DMAC2}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwAHB0DMAC2Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_AHB0DMAC1}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwAHB0DMAC1Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_AHB0DMAC0}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwAHB0DMAC0Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_AHBEXDMAC}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwAHBEXDMACPhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_EXBUS}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwEXBUSPhys)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_DTVIf}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwDTVIfPhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_APB1}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwAPB1Phys)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_PWM7}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwPWM7Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_PWM6}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwPWM6Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_PWM5}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwPWM5Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_PWM4}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwPWM4Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_PWM3}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwPWM3Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_PWM2}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwPWM2Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_PWM1}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwPWM1Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_PWM0}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwPWM0Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_GPIO}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwGPIOPhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_SYSCTRL}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwSYSCTRLPhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_eWDT}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHweWDTPhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_Timer5}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwTimer5Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_Timer4}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwTimer4Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_Timer3}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwTimer3Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_Timer2}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwTimer2Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_Timer1}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwTimer1Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_Timer0}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwTimer0Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_UART7}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwUART7Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_UART6}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwUART6Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_UART5}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwUART5Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_UART4}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwUART4Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_UART3}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwUART3Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_UART2}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwUART2Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_UART1}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwUART1Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_UART0}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwUART0Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_I2S3}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwI2S3Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_I2S2}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwI2S2Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_I2S1}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwI2S1Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_I2S0}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwI2S0Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_I2C}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwI2CPhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_CSI1}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwCSI1Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_CSI0}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwCSI0Phys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_SPDIF}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwSPDIFPhys)} } }, + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_SD}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwSDPhys)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_FPGA}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwFPGAPhys)} } }, + + { { {KHcrCat_MHA_HWBASE, KHcrKey_HwPhys_LAN}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KHwLANPhys)} } }, + +/* +HCR Setting values for DMA logical channel identifiers. +*/ + + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_SD0}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDMAChannelSD0)} } }, + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_SD1}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDMAChannelSD1)} } }, + + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_I2S0RX}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDMAChannelI2S0RX)} } }, + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_I2S0TX}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDMAChannelI2S0TX)} } }, + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_I2S1RX}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDMAChannelI2S1RX)} } }, + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_I2S1TX}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDMAChannelI2S1TX)} } }, + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_I2S2RX}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDMAChannelI2S2RX)} } }, + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_I2S2TX}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDMAChannelI2S2TX)} } }, + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_I2S3RX}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDMAChannelI2S3RX)} } }, + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_I2S3TX}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDMAChannelI2S3TX)} } }, + + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_UART0RX}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDMAChannelUART0RX)} } }, + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_UART0TX}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDMAChannelUART0TX)} } }, + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_UART1RX}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDMAChannelUART1RX)} } }, + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_UART1TX}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDMAChannelUART1TX)} } }, + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_UART2RX}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDMAChannelUART2RX)} } }, + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_UART2TX}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDMAChannelUART2TX)} } }, + + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_MemToMem0}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDmaMemToMem0)} } }, + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_MemToMem1}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDmaMemToMem1)} } }, + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_MemToMem2}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDmaMemToMem2)} } }, + { { {KHcrCat_MHA_DMA, KHcrKey_DmaCh_MemToMem3}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EDmaMemToMem3)} } } + +// +// Last entry must not end in a ',' as it is present in the enclosing file. +// }; + + +#endif // HCR_PSL_CONFIG_ASSP_INL + + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/hcr/hcr_psl_config_assp_inc.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/hcr/hcr_psl_config_assp_inc.inl Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file is part of the NE1_TB Variant Base Port +* Hardware Configuration Respoitory compiled repository in-line cpp. +* +*/ + + +/** +@file hcr_psl_config_assp_inc.inl +File includes the headers needed to compile the ASSP settings and their values +as held in the two other INL files: hcr_psl_config_assp.inl +and hcr_psl_config_assp_lsd.inl. These three files must compile cleanly +in the main hcr_psl_config.cpp file which includes the. + +@internalTechnology +*/ + + +#ifndef HCR_PSL_CONFIG_ASSP_INC_INL +#define HCR_PSL_CONFIG_ASSP_INC_INL + + +#include +#include + +#include + + +#endif // HCR_PSL_CONFIG_ASSP_INC_INL + + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/hcr/hcr_psl_config_assp_lsd.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/hcr/hcr_psl_config_assp_lsd.inl Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file is part of the NE1_TB Variant Base Port +* Hardware Configuration Respoitory compiled repository in-line cpp. +* +*/ + + +/** +@file hcr_psl_config_assp_lsd.inl +File provides large setting value definitions for the ASSP setting values +applicable to the NEC NaviEngine base port. + +@internalTechnology +*/ + + +#ifndef HCR_PSL_CONFIG_ASSP_LSD_INL +#define HCR_PSL_CONFIG_ASSP_LSD_INL + + +// No large setting values defined for MHA settings at present. + + +#endif // HCR_PSL_CONFIG_ASSP_LSD_INL + + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/hcr/hcrconfig_assp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/hcr/hcrconfig_assp.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,207 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file is part of the NE1_TB Variant Base Port +* Hardware Configuration Respoitory Published Setting IDs header. +* +*/ + + + +/** +@file hcrconfig_assp.h +File provides const uint definitions for the published set of HCR settings +identifiers applicable to the NEC NaviEngine base port ASSP part. + +@publishedPartner +@prototype +*/ + +#ifndef HCRCONFIG_ASSP_H +#define HCRCONFIG_ASSP_H + + + + +// -- INCLUDES ---------------------------------------------------------------- + +#include + + + +// -- CATEGORY ---------------------------------------------------------------- + + + +// -- KEYS -------------------------------------------------------------------- + + +/** +HCR Setting Keys for ASSP Hardware Block base virtual addresses for FMM and MMM. +*/ +#define HW_BASE 0x00001000 +const HCR::TElementId KHcrKey_HwBase_Uart0 = HW_BASE + 11; //< Serial port #0 +const HCR::TElementId KHcrKey_HwBase_Uart1 = HW_BASE + 12; //< Serial port #1 +const HCR::TElementId KHcrKey_HwBase_Uart2 = HW_BASE + 13; //< Serial port #2 + +const HCR::TElementId KHcrKey_HwBase_MPCorePrivate = HW_BASE + 21; //< 4KB of private MPcore region for SCU and Interrupt controller +const HCR::TElementId KHcrKey_HwBase_SCU = HW_BASE + 22; //< Snoop Control Unit +const HCR::TElementId KHcrKey_HwBase_IntIf = HW_BASE + 23; //< CPU interrupt interface +const HCR::TElementId KHcrKey_HwBase_IntDist = HW_BASE + 24; //< Global Interrupt Distributer + +const HCR::TElementId KHcrKey_HwBase_Timers = HW_BASE + 31; //< Six SoC timers +const HCR::TElementId KHcrKey_HwBase_Watchdog = HW_BASE + 32; //< eWDT (Watchdog Timer) +const HCR::TElementId KHcrKey_HwBase_SystemCtrl = HW_BASE + 33; //< System control unit + +const HCR::TElementId KHcrKey_HwBase_Display = HW_BASE + 41; //< SoC display controller + +const HCR::TElementId KHcrKey_HwBase_I2C = HW_BASE + 51; //< I2C +const HCR::TElementId KHcrKey_HwBase_I2S0 = HW_BASE + 52; //< I2S0 +const HCR::TElementId KHcrKey_HwBase_I2S1 = HW_BASE + 53; //< I2S1 +const HCR::TElementId KHcrKey_HwBase_I2S2 = HW_BASE + 54; //< I2S2 +const HCR::TElementId KHcrKey_HwBase_I2S3 = HW_BASE + 55; //< I2S3 + +const HCR::TElementId KHcrKey_HwBase_FPGA = HW_BASE + 61; //< FPGA registers +const HCR::TElementId KHcrKey_HwBase_CDDisp = HW_BASE + 62; //< LCD display +const HCR::TElementId KHcrKey_HwBase_TSP = HW_BASE + 63; //< Digitiser + +const HCR::TElementId KHcrKey_HwBase_SPDIF = HW_BASE + 64; //< SPDIF + +const HCR::TElementId KHcrKey_HwBase_CSI0 = HW_BASE + 71; //< CSI0 +const HCR::TElementId KHcrKey_HwBase_CSI1 = HW_BASE + 72; //< CSI1 + +const HCR::TElementId KHcrKey_HwBase_SDCtrl = HW_BASE + 81; //< SD + +const HCR::TElementId KHcrKey_HwBase_KDMACExBus = HW_BASE + 91; //< DMAC(4C) 4KB +const HCR::TElementId KHcrKey_HwBase_KDMAC32 = HW_BASE + 92; //< DMAC(8C) 20KB + +const HCR::TElementId KHcrKey_HwBase_Ethernet = HW_BASE + 101; //< Ethernet0 + +const HCR::TElementId KHcrKey_HwBase_GPIOBase = HW_BASE + 111; //< GPIO + +const HCR::TElementId KHcrKey_HwBase_PciBase = HW_BASE + 121; //< // PCI Bridges +const HCR::TElementId KHcrKey_HwBase_PciBridgeExtern = HW_BASE + 122; //< External PCI Bridge +const HCR::TElementId KHcrKey_HwBase_PciBridgeUsb = HW_BASE + 123; //< UsbHost dedicated PCI Bridge + +const HCR::TElementId KHcrKey_HwBase_UsbHWindow = HW_BASE + 131; //< Internal PCI window +#undef HW_BASE + + +/** +HCR Settings holding the DMA logical channel identifiers. +*/ +#define DMA_CH 0x00002000 +const HCR::TElementId KHcrKey_DmaCh_SD0 = DMA_CH + 11; //< +const HCR::TElementId KHcrKey_DmaCh_SD1 = DMA_CH + 12; //< + +const HCR::TElementId KHcrKey_DmaCh_I2S0RX = DMA_CH + 21; //< +const HCR::TElementId KHcrKey_DmaCh_I2S0TX = DMA_CH + 22; //< +const HCR::TElementId KHcrKey_DmaCh_I2S1RX = DMA_CH + 23; //< +const HCR::TElementId KHcrKey_DmaCh_I2S1TX = DMA_CH + 24; //< +const HCR::TElementId KHcrKey_DmaCh_I2S2RX = DMA_CH + 25; //< +const HCR::TElementId KHcrKey_DmaCh_I2S2TX = DMA_CH + 26; //< +const HCR::TElementId KHcrKey_DmaCh_I2S3RX = DMA_CH + 27; //< +const HCR::TElementId KHcrKey_DmaCh_I2S3TX = DMA_CH + 28; //< + +const HCR::TElementId KHcrKey_DmaCh_UART0RX = DMA_CH + 41; //< +const HCR::TElementId KHcrKey_DmaCh_UART0TX = DMA_CH + 42; //< +const HCR::TElementId KHcrKey_DmaCh_UART1RX = DMA_CH + 43; //< +const HCR::TElementId KHcrKey_DmaCh_UART1TX = DMA_CH + 44; //< +const HCR::TElementId KHcrKey_DmaCh_UART2RX = DMA_CH + 45; //< +const HCR::TElementId KHcrKey_DmaCh_UART2TX = DMA_CH + 46; //< + +const HCR::TElementId KHcrKey_DmaCh_MemToMem0 = DMA_CH + 61; //< +const HCR::TElementId KHcrKey_DmaCh_MemToMem1 = DMA_CH + 62; //< +const HCR::TElementId KHcrKey_DmaCh_MemToMem2 = DMA_CH + 63; //< +const HCR::TElementId KHcrKey_DmaCh_MemToMem3 = DMA_CH + 64; //< +#undef DMA_CH + +/** +HCR Settings holding the memory map physical addresses identifiers. +*/ +#define HW_PHYS 0x00003000 +const HCR::TElementId KHcrKey_HwPhys_BaseMPcorePrivate = HW_PHYS + 11; //< +const HCR::TElementId KHcrKey_HwPhys_DDR2RamBase = HW_PHYS + 12; //< +const HCR::TElementId KHcrKey_HwPhys_PCI = HW_PHYS + 13; //< +const HCR::TElementId KHcrKey_HwPhys_Internal = HW_PHYS + 14; //< + +const HCR::TElementId KHcrKey_HwPhys_AXI64IC2 = HW_PHYS + 21; //< +const HCR::TElementId KHcrKey_HwPhys_SATA = HW_PHYS + 22; //< +const HCR::TElementId KHcrKey_HwPhys_AXI64DMAC = HW_PHYS + 23; //< +const HCR::TElementId KHcrKey_HwPhys_Video = HW_PHYS + 24; //< +const HCR::TElementId KHcrKey_HwPhys_Disp = HW_PHYS + 25; //< +const HCR::TElementId KHcrKey_HwPhys_SGX = HW_PHYS + 26; //< + +const HCR::TElementId KHcrKey_HwPhys_CFWindow2 = HW_PHYS + 31; //< +const HCR::TElementId KHcrKey_HwPhys_CFWindow1 = HW_PHYS + 32; //< +const HCR::TElementId KHcrKey_HwPhys_CFWindow0 = HW_PHYS + 33; //< +const HCR::TElementId KHcrKey_HwPhys_ATA6CS1 = HW_PHYS + 34; //< +const HCR::TElementId KHcrKey_HwPhys_ATA6CS0 = HW_PHYS + 35; //< +const HCR::TElementId KHcrKey_HwPhys_USBH = HW_PHYS + 36; //< +const HCR::TElementId KHcrKey_HwPhys_AHB32PCIUSB = HW_PHYS + 37; //< +const HCR::TElementId KHcrKey_HwPhys_AHB32PCIExt = HW_PHYS + 38; //< +const HCR::TElementId KHcrKey_HwPhys_DDR2Reg = HW_PHYS + 39; //< +const HCR::TElementId KHcrKey_HwPhys_AHB0DMAC4 = HW_PHYS + 40; //< +const HCR::TElementId KHcrKey_HwPhys_AHB0DMAC3 = HW_PHYS + 41; //< +const HCR::TElementId KHcrKey_HwPhys_AHB0DMAC2 = HW_PHYS + 42; //< +const HCR::TElementId KHcrKey_HwPhys_AHB0DMAC1 = HW_PHYS + 43; //< +const HCR::TElementId KHcrKey_HwPhys_AHB0DMAC0 = HW_PHYS + 44; //< +const HCR::TElementId KHcrKey_HwPhys_AHBEXDMAC = HW_PHYS + 45; //< +const HCR::TElementId KHcrKey_HwPhys_EXBUS = HW_PHYS + 46; //< + +const HCR::TElementId KHcrKey_HwPhys_DTVIf = HW_PHYS + 50; //< +const HCR::TElementId KHcrKey_HwPhys_APB1 = HW_PHYS + 51; //< + +const HCR::TElementId KHcrKey_HwPhys_PWM7 = HW_PHYS + 60; //< +const HCR::TElementId KHcrKey_HwPhys_PWM6 = HW_PHYS + 61; //< +const HCR::TElementId KHcrKey_HwPhys_PWM5 = HW_PHYS + 62; //< +const HCR::TElementId KHcrKey_HwPhys_PWM4 = HW_PHYS + 63; //< +const HCR::TElementId KHcrKey_HwPhys_PWM3 = HW_PHYS + 64; //< +const HCR::TElementId KHcrKey_HwPhys_PWM2 = HW_PHYS + 65; //< +const HCR::TElementId KHcrKey_HwPhys_PWM1 = HW_PHYS + 66; //< +const HCR::TElementId KHcrKey_HwPhys_PWM0 = HW_PHYS + 67; //< +const HCR::TElementId KHcrKey_HwPhys_GPIO = HW_PHYS + 68; //< +const HCR::TElementId KHcrKey_HwPhys_SYSCTRL = HW_PHYS + 69; //< +const HCR::TElementId KHcrKey_HwPhys_eWDT = HW_PHYS + 70; //< +const HCR::TElementId KHcrKey_HwPhys_Timer5 = HW_PHYS + 71; //< +const HCR::TElementId KHcrKey_HwPhys_Timer4 = HW_PHYS + 72; //< +const HCR::TElementId KHcrKey_HwPhys_Timer3 = HW_PHYS + 73; //< +const HCR::TElementId KHcrKey_HwPhys_Timer2 = HW_PHYS + 74; //< +const HCR::TElementId KHcrKey_HwPhys_Timer1 = HW_PHYS + 75; //< +const HCR::TElementId KHcrKey_HwPhys_Timer0 = HW_PHYS + 76; //< +const HCR::TElementId KHcrKey_HwPhys_UART7 = HW_PHYS + 77; //< +const HCR::TElementId KHcrKey_HwPhys_UART6 = HW_PHYS + 78; //< +const HCR::TElementId KHcrKey_HwPhys_UART5 = HW_PHYS + 79; //< +const HCR::TElementId KHcrKey_HwPhys_UART4 = HW_PHYS + 80; //< +const HCR::TElementId KHcrKey_HwPhys_UART3 = HW_PHYS + 81; //< +const HCR::TElementId KHcrKey_HwPhys_UART2 = HW_PHYS + 82; //< +const HCR::TElementId KHcrKey_HwPhys_UART1 = HW_PHYS + 83; //< +const HCR::TElementId KHcrKey_HwPhys_UART0 = HW_PHYS + 84; //< +const HCR::TElementId KHcrKey_HwPhys_I2S3 = HW_PHYS + 85; //< +const HCR::TElementId KHcrKey_HwPhys_I2S2 = HW_PHYS + 86; //< +const HCR::TElementId KHcrKey_HwPhys_I2S1 = HW_PHYS + 87; //< +const HCR::TElementId KHcrKey_HwPhys_I2S0 = HW_PHYS + 88; //< +const HCR::TElementId KHcrKey_HwPhys_I2C = HW_PHYS + 89; //< +const HCR::TElementId KHcrKey_HwPhys_CSI1 = HW_PHYS + 90; //< +const HCR::TElementId KHcrKey_HwPhys_CSI0 = HW_PHYS + 91; //< +const HCR::TElementId KHcrKey_HwPhys_SPDIF = HW_PHYS + 92; //< +const HCR::TElementId KHcrKey_HwPhys_SD = HW_PHYS + 93; //< + +const HCR::TElementId KHcrKey_HwPhys_FPGA = HW_PHYS + 100; //< + + +const HCR::TElementId KHcrKey_HwPhys_LAN = HW_PHYS + 110; //< +#undef HW_PHYS + +#endif // HCRCONFIG_ASSP_H diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/highrestimer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/highrestimer.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Defintions for High resolution timer +* +*/ + + + + + +#ifndef __HIGHRESTIMER_H__ +#define __HIGHRESTIMER_H__ + +/** + * Macro indicating that a high resolution timer is supported. + */ +#define HAS_HIGH_RES_TIMER + +#ifdef __MEMMODEL_DIRECT__ +#define HIGH_RES_COUNT_HW_ADDR 0x18036800 /* address of timer 2 counter */ +#else +#define HIGH_RES_COUNT_HW_ADDR 0xC6003800 /* address of timer 2 counter */ +#endif + +/** + * Assembler macro to get the the current value of the high res timer and place + * it in the specified register. + */ +#define GET_HIGH_RES_TICK_COUNT(Rd) \ + asm("ldr "#Rd", = %a0" : : "i" (HIGH_RES_COUNT_HW_ADDR)); \ + asm("ldr "#Rd", ["#Rd"]") + +/** + * The frequency of the timer in Hz. + */ +const TInt KHighResTimerFrequency = 2083333; // 200MHz/(3*32) + +/** + * Macro indicating that the timer counts up if defined. + */ +#define HIGH_RES_TIMER_COUNTS_UP + +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/i2s/i2s_pil.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/i2s/i2s_pil.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,809 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* bsp\hwip_nec_navienegine\navienegine_assp\i2s\i2s_pil.cpp +* +*/ + + + +#include +#include "navi_i2s.h" + +#define CHANNEL_ID_FROM_INTERFACE_ID(aId) (TUint16)aId // channel ID on bottom 16 bits (as returned by Configuration Repository) + +TInt TI2sManager::iChannelsNum = 0; +DI2sChannelBase** TI2sManager::iChannels = 0; + +TInt TI2sManager::DoCreate() + { + TInt err=KErrNone; + // (TBD) Must call into ConfRep to obtain the number of channels present and store it in iChannelsNum and create a list of all interfaces supported. + // Then iterate through the list of interfaces and create channels. + // This way, each channel implementation can be written independently from the others, and brroght + // together at the end at the cost of a virtaul pointer dereferencing. (Incidentaly that is totally + // irrelevant for the NaviEngine implementation where all channels are implemented in a single file + // but we present this code as an example of how it could be done in a situation of need) + + iChannelsNum=4; // TBD: for now, in future need to call into ConfRep + + TInt* chanArray=(TInt*)Kern::Alloc(iChannelsNum*sizeof(TInt)); // allocate a temporary array of interface Ids to populate with ConfRep data + if(!chanArray) + return KErrNoMemory; + + DI2sChannelBase** channels=(DI2sChannelBase**)Kern::Alloc(iChannelsNum*sizeof(DI2sChannelBase*)); // allocate an array of pointers to channels (stored in iChannels) + if(!channels) + return KErrNoMemory; + + for(TInt i=0; i= TI2sManager::iChannelsNum) || !aConfig) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->ConfigureInterface(aConfig); + } + +/** + Reads the current configuration. + + @param aInterfaceId The interface Id. + @param aConfig On return, the buffer passed is filled with the current configuration. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid. + */ +EXPORT_C TInt I2s::GetInterfaceConfiguration(TInt aInterfaceId, TDes8& aConfig) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->GetInterfaceConfiguration(aConfig); + } + +/** + Sets the sampling rate. + + @param aInterfaceId The interface Id. + @param aSamplingRate One of TI2sSamplingRate. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if the sampling rate is not supported by this interface; + KErrInUse, if interface is not quiescient (a transfer is under way). + */ +EXPORT_C TInt I2s::SetSamplingRate(TInt aInterfaceId, TI2sSamplingRate aSamplingRate) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->SetSamplingRate(aSamplingRate); + } + +/** + Reads the sampling rate. + + @param aInterfaceId The interface Id. + @param aSamplingRate On return, contains one of TI2sSamplingRate. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid. + */ +EXPORT_C TInt I2s::GetSamplingRate(TInt aInterfaceId, TInt& aSamplingRate) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->GetSamplingRate(aSamplingRate); + } + +/** + Sets the frame length and format. + + @param aInterfaceId The interface Id. + @param aFrameLength One of TI2sFrameLength. + @param aLeftFramePhaseLength The length of the left frame phase (in number of data bits). + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if the frame length or format are not supported by this interface; + KErrInUse, if interface is not quiescient (a transfer is under way). + + The implementation calculates the Right frame phase length as (FrameLength - LeftFramePhaseLength) + */ +EXPORT_C TInt I2s::SetFrameLengthAndFormat(TInt aInterfaceId, TI2sFrameLength aFrameLength, TInt aLeftFramePhaseLength) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->SetFrameLengthAndFormat(aFrameLength, aLeftFramePhaseLength); + } + +/** + Reads the frame format. + + @param aInterfaceId The interface Id. + @param aLeftFramePhaseLength On return, contains the length of the left frame phase. + @param aRightFramePhaseLength On return, contains the length of the right frame phase. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid. + */ +EXPORT_C TInt I2s::GetFrameFormat(TInt aInterfaceId, TInt& aLeftFramePhaseLength, TInt& aRightFramePhaseLength) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->GetFrameFormat(aLeftFramePhaseLength, aRightFramePhaseLength); + } + +/** + Sets the sample length for a frame phase (left or right). + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aSampleLength One of TI2sSampleLength. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if the sample length for the frame phase selected is not supported by this interface; + KErrInUse, if interface is not quiescient (a transfer is under way). + */ +EXPORT_C TInt I2s::SetSampleLength(TInt aInterfaceId, TI2sFramePhase aFramePhase, TI2sSampleLength aSampleLength) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->SetSampleLength(aFramePhase, aSampleLength); + } + +/** + Reads the sample length for a frame phase (left or right). + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aSampleLength On return, contains the sample length for the frame phase indicated by aFramePhase. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid. + */ +EXPORT_C TInt I2s::GetSampleLength(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt& aSampleLength) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->GetSampleLength(aFramePhase, aSampleLength); + } + +/** + Sets the number of delay cycles for a frame phase (left or right). + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aDelayCycles The number of delay cycles to be introduced for the frame phase indicated by aFramePhase. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if the number of delay cycles for the frame phase selected is not supported by this interface; + KErrInUse, if interface is not quiescient (a transfer is under way). + + Each delay cycle has a duration of a bit clock cycle. Delay cycles are inserted between the start of the frame and the start of data. + */ +EXPORT_C TInt I2s::SetDelayCycles(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt aDelayCycles) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->SetDelayCycles(aFramePhase, aDelayCycles); + } + +/** + Reads the number of delay cycles for a frame phase (left or right). + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aDelayCycles On return, contains the number of delay cycles for the frame phase indicated by aFramePhase. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid. + */ +EXPORT_C TInt I2s::GetDelayCycles(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt& aDelayCycles) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->GetDelayCycles(aFramePhase, aDelayCycles); + } + +/** + Reads the receive data register for a frame phase. + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aData On return, contains the receive data register contents. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if reading the receive data register is not supported (e.g. when if DMA is enabled) + KErrNotReady, if the interface is not ready. + + If the implementation has a combined receive/transmit register - half duplex operation only - this API is used to read from it. + If the implementation only supports a single receive register for both frame phases, the aFramePhase argument shall be ignored and the + API shall return the contents of the single register. The user of the API shall use the ReadRegisterModeStatus() API to determine + which frame phase the data corresponds to. + */ +EXPORT_C TInt I2s::ReadReceiveRegister(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt& aData) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->ReadReceiveRegister(aFramePhase, aData); + } + +/** + Writes to the transmit data register for a frame phase. + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aData The data to be written. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if writing to the receive data register is not supported (e.g. when if DMA is enabled) + KErrNotReady, if the interface is not ready. + + If the implementation has a combined receive/transmit register - half duplex operation only - this API is used to write to it. + If the implementation only supports a single transmit register for both frame phases, the aFramePhase argument shall be ignored and the + API shall write to the single register. The user of the API shall use the ReadRegisterModeStatus() API to determine under which frame + phase the data corresponds will be transmitted. + */ +EXPORT_C TInt I2s::WriteTransmitRegister(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt aData) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->WriteTransmitRegister(aFramePhase, aData); + } + +/** + Reads the transmit data register for a frame phase. + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aData On return, contains the transmit data register contents. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if reading the transmit data register is not supported; + KErrNotReady, if the interface is not ready. + + If the implementation has a combined receive/transmit register this API is used to read from it (equivalent to ReadReceiveRegister()). + If the implementation only supports a single transmit register for both frame phases, the aFramePhase argument shall be ignored and the + API shall return the contents of the single register. The user of the API shall use the ReadRegisterModeStatus() API to determine + which frame phase the data corresponds to. + */ +EXPORT_C TInt I2s::ReadTransmitRegister(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt& aData) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->ReadTransmitRegister(aFramePhase, aData); + } + +/** + Reads the Register PIO access mode status flags for a frame phase. + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aFlags On return, contains a bitmask with the status flags for the frame phase selected (see TI2sFlags). + A bit set to "1" indicates the condition described by the corresponding flag is occurring. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if reading the status flags for Register PIO mode is not supported by this implementation. + + The client driver may use one of IS_I2s_ macros to determine the status of individual conditions. + */ +EXPORT_C TInt I2s::ReadRegisterModeStatus(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt& aFlags) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->ReadRegisterModeStatus(aFramePhase, aFlags); + } + +/** + Enables Register PIO access mode related interrupts for a frame phase. + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aInterrupt A bitmask containing the relevant interrupt flags (see TI2sFlags). + Bits set to "1" enable the corresponding interrupts. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if one of the selected interrupt conditions cannot be generated by this implementation. + + If the implementation only supports single transmit and receive registers for both frame phases, the aFramePhase argument is + ignored. + */ +EXPORT_C TInt I2s::EnableRegisterInterrupts(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt aInterrupt) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->EnableRegisterInterrupts(aFramePhase, aInterrupt); + } + +/** + Disables Register PIO access mode related interrupts for a frame phase. + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aInterrupt A bitmask containing the relevant interrupt flags (see TI2sFlags). + Bits set to "1" disable the corresponding interrupts. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if one of the selected interrupt conditions cannot be generated by this implementation. + + If the implementation only supports single transmit and receive registers for both frame phases, the aFramePhase argument is + ignored. + */ +EXPORT_C TInt I2s::DisableRegisterInterrupts(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt aInterrupt) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->DisableRegisterInterrupts(aFramePhase, aInterrupt); + } + +/** + Reads the Register PIO access mode interrupt mask for a frame phase. + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aEnabled On return, contains a bitmask with the interrupts which are enabled for the frame phase selected (see TI2sFlags). + A bit set to "1" indicates the corresponding interrupt is enabled. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if one of the selected interrupt conditions cannot be generated by this implementation. + + If the implementation only supports single transmit and receive registers for both frame phases, the aFramePhase argument is + ignored. + */ +EXPORT_C TInt I2s::IsRegisterInterruptEnabled(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt& aEnabled) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->IsRegisterInterruptEnabled(aFramePhase, aEnabled); + } + +/** + Enables receive and/or transmit FIFO on a per frame phase basis. + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aFifoMask A bitmask specifying which FIFO direction(s) - receive and/or transmit - are to be enabled for the frame + phase selected (see TI2sDirection). + Bits set to "1" enable the corresponding FIFO. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if the implementation does no support FIFOs. + + If the implementation has a combined receive/transmit FIFO - half duplex operation only - then aFifoMask is ignored. + If the implementation only supports a single FIFO for both frame phases then aFramePhase is ignored. + */ +EXPORT_C TInt I2s::EnableFIFO(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt aFifoMask) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->EnableFIFO(aFramePhase, aFifoMask); + } + +/** + Disables receive and/or transmit FIFO on a per frame phase basis. + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aFifoMask A bitmask specifying which FIFO direction(s) - receive and/or transmit - are to be disabled for the frame + phase selected (see TI2sDirection). + Bits set to "1" disable the corresponding FIFO. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if the implementation does no support FIFOs. + + If the implementation has a combined receive/transmit FIFO - half duplex operation only - then aFifoMask is ignored. + If the implementation only supports a single FIFO for both frame phases then aFramePhase is ignored. + */ +EXPORT_C TInt I2s::DisableFIFO(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt aFifoMask) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->DisableFIFO(aFramePhase, aFifoMask); + } + +/** + Reads the enabled state of a frame phase's FIFOs. + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aEnabled On return, contains a bitmask indicating which FIFOs which are enabled for the frame phase selected (see TI2sDirection). + A bit set to "1" indicates the corresponding FIFO is enabled. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if the implementation does no support FIFOs. + + If the implementation has a combined receive/transmit FIFO - half duplex operation only - then aEnabled will have + both Rx and Tx bits set when the FIFO is enabled. + If the implementation only supports a single FIFO for both frame phases then aFramePhase is ignored. + */ +EXPORT_C TInt I2s::IsFIFOEnabled(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt& aEnabled) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->IsFIFOEnabled(aFramePhase, aEnabled); + } + +/** + Sets the receive or transmit FIFO threshold on a per frame phase basis. + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aDirection One of TDirection. + @param aThreshold A threshold level at which a receive FIFO is considered full or a transmit FIFO is considered empty. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if the implementation does no support FIFOs; + KErrOverflow if the threshold level requested exceeds the FIFO length (or the admissible highest level allowed) + KErrUnderflow if the threshold level requested is less than the minimum threshold allowed. + + If the implementation has a combined receive/transmit FIFO - half duplex operation only - then aDirection is ignored. + If the implementation only supports a single FIFO for both frame phases then aFramePhase is ignored. + */ +EXPORT_C TInt I2s::SetFIFOThreshold(TInt aInterfaceId, TI2sFramePhase aFramePhase, TI2sDirection aDirection, TInt aThreshold) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->SetFIFOThreshold(aFramePhase, aDirection, aThreshold); + } + +/** + Reads the FIFO PIO access mode status flags for a frame phase. + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aFlags On return, contains a bitmask with the status flags for the frame phase selected (see TI2sFlags). + A bit set to "1" indicates the condition described by the corresponding flag is occurring. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if reading the status flags for FIFO PIO mode is not supported by this implementation. + + The client driver may use one of IS_I2s_ macros to determine the status of individual conditions. + If the implementation has a combined receive/transmit FIFO - half duplex operation only - then aFlags will be set according + to which operation (receive/transmit) is undergoing. + If the implementation only supports a single FIFO for both frame phases then aFramePhase is ignored. + */ +EXPORT_C TInt I2s::ReadFIFOModeStatus(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt& aFlags) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->ReadFIFOModeStatus(aFramePhase, aFlags); + } + +/** + Enables FIFO related interrupts for a frame phase. + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aInterrupt A bitmask containing the relevant interrupt flags (see TI2sFlags). + Bits set to "1" enable the corresponding interrupts. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if one of the selected interrupt conditions cannot be generated by this implementation. + + If the implementation only supports single transmit and receive FIFO for both frame phases, the aFramePhase argument is + ignored. + */ +EXPORT_C TInt I2s::EnableFIFOInterrupts(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt aInterrupt) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->EnableFIFOInterrupts(aFramePhase, aInterrupt); + } + +/** + Disables FIFO related interrupts for a frame phase. + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aInterrupt A bitmask containing the relevant interrupt flags (see TI2sFlags). + Bits set to "1" disable the corresponding interrupts. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if one of the selected interrupt conditions cannot be generated by this implementation. + + If the implementation only supports single transmit and receive FIFO for both frame phases, the aFramePhase argument is + ignored. + */ +EXPORT_C TInt I2s::DisableFIFOInterrupts(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt aInterrupt) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->DisableFIFOInterrupts(aFramePhase, aInterrupt); + } + +/** + Reads the FIFO interrupt masks for a frame phase. + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aEnabled On return, contains a bitmask with the interrupts which are enabled for the frame phase selected (see TI2sFlags). + A bit set to "1" indicates the corresponding interrupt is enabled. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if one of the selected interrupt conditions cannot be generated by this implementation. + */ +EXPORT_C TInt I2s::IsFIFOInterruptEnabled(TInt aInterfaceId, TI2sFramePhase aFramePhase, TInt& aEnabled) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->IsFIFOInterruptEnabled(aFramePhase, aEnabled); + } + +/** + Reads the receive or transmit FIFO current level on a per frame phase basis. + + @param aInterfaceId The interface Id. + @param aFramePhase One of TI2sFramePhase. + @param aDirection One of TDirection. + @param aLevel On return, contains the current level for the FIFO described by the (aFramePhase,aDirection) pair. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if the implementation does no support FIFOs. + + If the implementation has a combined receive/transmit FIFO - half duplex operation only - then aDirection is ignored. + If the implementation only supports a single FIFO for both frame phases then aFramePhase is ignored. + */ +EXPORT_C TInt I2s::ReadFIFOLevel(TInt aInterfaceId, TI2sFramePhase aFramePhase, TI2sDirection aDirection, TInt& aLevel) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->ReadFIFOLevel(aFramePhase, aDirection, aLevel); + } + +/** + Enables receive and/or transmit DMA. + + @param aInterfaceId The interface Id. + @param aFifoMask A bitmask specifying which directions - receive and/or transmit - is DMA to be enabled (see TI2sDirection). + Bits set to "1" enable DMA. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if the implementation does no support DMA. + + If the implementation has a combined receive/transmit FIFO - half duplex operation only - then aFifoMask is ignored. + */ +EXPORT_C TInt I2s::EnableDMA(TInt aInterfaceId, TInt aFifoMask) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->EnableDMA(aFifoMask); + } + +/** + Disables receive and/or transmit DMA. + + @param aInterfaceId The interface Id. + @param aFifoMask A bitmask specifying which directions - receive and/or transmit - is DMA to be disabled (see TI2sDirection). + Bits set to "1" disable DMA. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if the implementation does no support DMA. + + If the implementation has a combined receive/transmit FIFO - half duplex operation only - then aFifoMask is ignored. + */ +EXPORT_C TInt I2s::DisableDMA(TInt aInterfaceId, TInt aFifoMask) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->DisableDMA(aFifoMask); + } + +/** + Reads the enabled state of DMA. + + @param aInterfaceId The interface Id. + @param aEnabled On return, contains a bitmask indicating if DMA enabled for the corresponding directions (see TI2sDirection). + A bit set to "1" indicates DMA is enabled for the corresponding direction. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid; + KErrNotSupported, if the implementation does no support FIFOs. + + If the implementation has a combined receive/transmit FIFO - half duplex operation only - then aEnabled will have + both Rx and Tx bits set when the DMA is enabled. + */ +EXPORT_C TInt I2s::IsDMAEnabled(TInt aInterfaceId, TInt& aEnabled) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->IsDMAEnabled(aEnabled); + } + +/** + Starts data transmission and/or data reception unless interface is a Controller; + if device is also a Master, starts generation of data synchronisation signals. + + @param aInterfaceId The interface Id. + @param aDirection A bitmask made of TI2sDirection values. The value is ignored if interface is a Controller. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid or if aDirection is invalid (i.e. negative, 0 or greater than 3) + KErrNotSupported, if one of the transfer directions selected is not supported on this interface; + KErrInUse, if interface has a bidirectional data port and an access in the opposite direction is underway; + KErrNotReady, if interface is not ready (e.g. incomplete configuration). + + Start() is idempotent, attempting to start an already started interface has no effect (returns KErrNone). + */ +EXPORT_C TInt I2s::Start(TInt aInterfaceId, TInt aDirection) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->Start(aDirection); + } + +/** + Stops data transmission and/or data reception; + if device is also a Master, stops generation of data synchronisation signals. + + @param aInterfaceId The interface Id. + @param aDirection A bitmask made of TI2sDirection values. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid or if aDirection is invalid (i.e. negative, 0 or greater than 3) + KErrNotSupported, if one of the transfer directions selected is not supported on this interface. + + Stop() is idempotent, attempting to stop an already started interface has no effect (returns KErrNone). + */ +EXPORT_C TInt I2s::Stop(TInt aInterfaceId, TInt aDirection) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->Stop(aDirection); + } + +/** + Checks if a transmission or a reception is underway. + + @param aInterfaceId The interface Id. + @param aDirection One of TI2sDirection. + @param aStarted On return, contains ETrue if the the access is underway, EFalse otherwise. + + @return KErrNone, if successful; + KErrArgument, if aInterfaceId is invalid or if aDirection is invalid (i.e. negative, 0 or greater than 3) + KErrNotSupported, if one of the transfer directions selected is not supported on this interface. + + If the interface is a Controller and a bus operation is underway, ETrue is returned regardless of aDirection. + */ +EXPORT_C TInt I2s::IsStarted(TInt aInterfaceId, TI2sDirection aDirection, TBool& aStarted) + { + TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId); + if(chanId >= TI2sManager::iChannelsNum) + return KErrArgument; + + return TI2sManager::iChannels[chanId]->IsStarted(aDirection, aStarted); + } + +// dll entry point.. +DECLARE_STANDARD_EXTENSION() + { + __KTRACE_OPT(KBOOT, Kern::Printf("Starting I2S Extension")); + // coverity[alloc_fn] + TI2sManager* pD = new TI2sManager; + TInt r=KErrNoMemory; + if (pD) + r=pD->DoCreate(); + return r; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/i2s/i2s_psl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/i2s/i2s_psl.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,960 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* bsp\nwip_nec_naviengine\naviengine_assp\i2s\i2s_psl.cpp +* +*/ + + + +#include "navi_i2s.h" +#include + +#ifdef __SMP__ +static TSpinLock I2sLock = TSpinLock(TSpinLock::EOrderGenericIrqLow2); +#endif + +// All channels have the same configuration. +// base for registers are shifted for each channel by 0x400 (1<<10) +#define HW_CHAN_SHIFT 10 + +// Registers +// these macros will return register address for a given interface +#define KHwI2SControl(intefaceId) ((KHwBaseI2S0 + KHoI2SCtrl) + (intefaceId << HW_CHAN_SHIFT)) +#define KHwI2SFifoControl(intefaceId) ((KHwBaseI2S0 + KHoI2SFifoCtrl) + (intefaceId << HW_CHAN_SHIFT)) +#define KHwI2SFifoStatus(intefaceId) ((KHwBaseI2S0 + KHoI2SFifoSts) + (intefaceId << HW_CHAN_SHIFT)) +#define KHwI2SInterruptFlag(intefaceId) ((KHwBaseI2S0 + KHoI2SIntFlg) + (intefaceId << HW_CHAN_SHIFT)) +#define KHwI2SInterruptMask(intefaceId) ((KHwBaseI2S0 + KHoI2SIntMask) + (intefaceId << HW_CHAN_SHIFT)) +#define KHwI2SDataIn(intefaceId) ((KHwBaseI2S0 + KHoI2SRx) + (intefaceId << HW_CHAN_SHIFT)) +#define KHwI2SDataOut(intefaceId) ((KHwBaseI2S0 + KHoI2STx) + (intefaceId << HW_CHAN_SHIFT)) + +#define AsspIsBitSet(addr, bit) (AsspRegister::Read32(addr)& (bit)) +#define CLEARMASK(shift,len) (((1 << len) - 1) << shift) +#define AsspGetBits(w,shift,len) ((AsspRegister::Read32(w) >> shift) & ((1 << (len)) - 1)) +#define AsspSetBits(w,set,shift,len) (AsspRegister::Modify32(w, (CLEARMASK(shift, len)) , (set << shift))) + + +NONSHARABLE_CLASS(D2sChannelNE1_TB) : public DI2sChannelBase + { +public: + D2sChannelNE1_TB(TInt aInterfaceId); + + virtual TInt ConfigureInterface(TDes8* aConfig); + virtual TInt GetInterfaceConfiguration(TDes8& aConfig); + virtual TInt SetSamplingRate(TInt aSamplingRate); + virtual TInt GetSamplingRate(TInt& aSamplingRate); + virtual TInt SetFrameLengthAndFormat(TInt aFrameLength, TInt aLeftFramePhaseLength); + virtual TInt GetFrameFormat(TInt& aLeftFramePhaseLength, TInt& aRightFramePhaseLength); + virtual TInt SetSampleLength(TInt aFramePhase, TInt aSampleLength); + virtual TInt GetSampleLength(TInt aFramePhase, TInt& aSampleLength); + virtual TInt SetDelayCycles(TInt aFramePhase, TInt aDelayCycles); + virtual TInt GetDelayCycles(TInt aFramePhase, TInt& aDelayCycles); + virtual TInt ReadReceiveRegister(TInt aFramePhase, TInt& aData); + virtual TInt WriteTransmitRegister(TInt aFramePhase, TInt aData); + virtual TInt ReadTransmitRegister(TInt aFramePhase, TInt& aData); + virtual TInt ReadRegisterModeStatus(TInt aFramePhase, TInt& aFlags); + virtual TInt EnableRegisterInterrupts(TInt aFramePhase, TInt aInterrupt); + virtual TInt DisableRegisterInterrupts(TInt aFramePhase, TInt aInterrupt); + virtual TInt IsRegisterInterruptEnabled(TInt aFramePhase, TInt& aEnabled); + virtual TInt EnableFIFO(TInt aFramePhase, TInt aFifoMask); + virtual TInt DisableFIFO(TInt aFramePhase, TInt aFifoMask); + virtual TInt IsFIFOEnabled(TInt aFramePhase, TInt& aEnabled); + virtual TInt SetFIFOThreshold(TInt aFramePhase, TInt aDirection, TInt aThreshold); + virtual TInt ReadFIFOModeStatus(TInt aFramePhase, TInt& aFlags); + virtual TInt EnableFIFOInterrupts(TInt aFramePhase, TInt aInterrupt); + virtual TInt DisableFIFOInterrupts(TInt aFramePhase, TInt aInterrupt); + virtual TInt IsFIFOInterruptEnabled(TInt aFramePhase, TInt& aEnabled); + virtual TInt ReadFIFOLevel(TInt aFramePhase, TInt aDirection, TInt& aLevel); + virtual TInt EnableDMA(TInt aFifoMask); + virtual TInt DisableDMA(TInt aFifoMask); + virtual TInt IsDMAEnabled(TInt& aEnabled); + virtual TInt Start(TInt aDirection); + virtual TInt Stop(TInt aDirection); + virtual TInt IsStarted(TInt aDirection, TBool& aStarted); + +private: + TBool iConfigured; + TInt iLastPhaseInWriteFifo; + TInt iLastPhaseInReadFifo; + }; + +// this static method, creates the DI2sChannelBase corresponding +// to the interfaceId passed and return the channel +// NB: if each channel was implemented independently (e.g. on a separate file) +// this function would have to be provided spearately and know how to map +// the interface ID to the appropriate channel object to be created +// (e.g. each channel would have a different implementation D2sChannelXXX +// and this function call the appropriate constructor for each interface Id) + +TInt DI2sChannelBase::CreateChannels(DI2sChannelBase*& aChannel, TInt aInterfaceId) + { + DI2sChannelBase* chan = new D2sChannelNE1_TB(aInterfaceId); + if (!chan) + { + return KErrNoMemory; + } + + aChannel = chan; + + return KErrNone; + } + + +// Default constructor. +D2sChannelNE1_TB::D2sChannelNE1_TB(TInt aInterfaceId): + iConfigured(EFalse), + iLastPhaseInWriteFifo(I2s::ERight), // the first phase in write fifo should be left, so initialize to right + iLastPhaseInReadFifo(I2s::ERight) // the first phase in read fifo should be left, so initialize to right + { + iInterfaceId=aInterfaceId; + } + +TInt D2sChannelNE1_TB::ConfigureInterface(TDes8 *aConfig) + { + __KTRACE_OPT(KDLL, Kern::Printf("DI2sChannelNE1_TB::ConfigureInterfaceInterface (Id: %d)", iInterfaceId)); + + if(AsspIsBitSet(KHwI2SControl(iInterfaceId), KHtI2SCtrl_TEN | KHtI2SCtrl_REN)) + { + return KErrInUse; + } + + TI2sConfigBufV01 &conf = ((TI2sConfigBufV01&)*aConfig); + + // this interface doesn's support EController mode + if (conf().iType == I2s::EController) + { + return KErrNotSupported; + } + + if(conf().iRole == I2s::EMaster) + { + AsspRegister::Modify32(KHwI2SControl(iInterfaceId), 0, KHtI2SCtrl_MSMODE); + } + + // copy configuration.. it will be used in Start/Stop + iConfig = conf(); // ok, thread context only and one client thread per channel + + // select I2S format + AsspSetBits(KHwI2SControl(iInterfaceId), 4, KHsI2SCtrl_FORMAT, 3); + + iConfigured = ETrue; // this API can only be called in thread context and we assume that a channel is for use of a single thread + + return KErrNone; + } + +TInt D2sChannelNE1_TB::GetInterfaceConfiguration(TDes8 &aConfig) + { + if (!iConfigured) // this API can only be called in thread context and we assume that a channel is for use of a single thread + { + aConfig.SetLength(0); //no configuration present yet.. + } + else + { + TPckgBuf conf(iConfig); + aConfig.Copy(conf); + } + return KErrNone; + } + +TInt D2sChannelNE1_TB::SetSamplingRate(TInt aSamplingRate) + { + if (iConfig.iRole == I2s::ESlave) + { + return KErrNotSupported; + } + + if (AsspIsBitSet(KHwI2SControl(iInterfaceId), KHtI2SCtrl_TEN | KHtI2SCtrl_REN)) + { + return KErrInUse; + } + + TUint32 val = 0, div = 0; + + switch(aSamplingRate) + { + case I2s::E8KHz: // 0000: 8 kHz + div = 1; // MCLK = 24.5760 MHz(1*) + break; + + case I2s::E11_025KHz: // 1000: 11.025 kHz + val = 8; + div = 4; // MCLK = 33.8688 MHz(4*) or 22.5792(5*) or 16.9344 MHz(6) + break; + + case I2s::E12KHz: // 0001: 12 kHz + val = 1; + div = 1; // MCLK = 24.5760 MHz(1*) or 18.432MHz(2) + break; + + case I2s::E16KHz: // 0010: 16 kHz + val = 2; + div = 1; // MCLK = 24.5760 MHz(1*) + break; + + case I2s::E22_05KHz: // 1001: 22.05 kHz + val = 9; + div = 4; // MCLK = 33.8688 MHz(4*) or 22.5792(5*) or 16.9344 MHz(6) + break; + + case I2s::E24KHz: // 0011: 24 kHz + val = 3; + div = 1; // MCLK = 24.5760 MHz(1*) or 18.432MHz(2) + break; + + case I2s::E32KHz: // 0100: 32 kHz + val = 4; + div = 1; // MCLK = 24.5760 MHz + break; + + case I2s::E44_1KHz: // 1010: 44.1 kHz + val = 10; + div = 4; // MCLK = 33.8688 MHz(4*) or 22.5792(5*) or 16.9344 MHz(6) + break; + + case I2s::E48KHz: // 0101: 48 kHz + val = 5; + div = 2; // MCLK = 24.5760 MHz(1*) or 18.432MHz(2) + break; + + default: + return KErrNotSupported; + } + + TInt irq=__SPIN_LOCK_IRQSAVE(I2sLock); // seems that we must guarantee the following sequence is uninterrupted... + // before changing FSCLKSEL and/or FSMODE - mask I2S bit + // MSK_I2Sx (x=0:3): bits 18:21 in MaskCtrl Register of the System Ctrl Unit + AsspRegister::Modify32(KHwBaseSCU + KHoSCUClockMaskCtrl, 0, (1<>KHsI2SCtrl_FCKLKSEL) & 0xf; + + switch(val) + { + case 0: + aSamplingRate = I2s::E8KHz; // 0000: 8 kHz + break; + + case 8: + aSamplingRate = I2s::E11_025KHz; // 1000: 11.025 kHz + break; + + case 1: + aSamplingRate = I2s::E12KHz; // 0001: 12 kHz + break; + + case 2: + aSamplingRate = I2s::E16KHz; // 0010: 16 kHz + break; + + case 9: + aSamplingRate = I2s::E22_05KHz; // 1001: 22.05 kHz + break; + + case 3: + aSamplingRate = I2s::E24KHz; // 0011: 24 kHz + break; + + case 4: + aSamplingRate = I2s::E32KHz; // 0100: 32 kHz + break; + + case 10: + aSamplingRate = I2s::E44_1KHz; // 1010: 44.1 kHz + break; + + case 5: + aSamplingRate = I2s::E48KHz; // 0101: 48 kHz + break; + } + + return KErrNone; + } + +TInt D2sChannelNE1_TB::SetFrameLengthAndFormat(TInt aFrameLength, TInt /*aLeftFramePhaseLength*/) + { + if (AsspIsBitSet(KHwI2SControl(iInterfaceId), KHtI2SCtrl_TEN | KHtI2SCtrl_REN)) + { + return KErrInUse; + } + + TUint32 val=0; + + switch(aFrameLength) + { + case I2s::EFrame32Bit: + val = 0; + break; + + case I2s::EFrame48Bit: + val = 1; + break; + + case I2s::EFrame64Bit: + val = 2; + break; + + case I2s::EFrame128Bit: + val = 3; + break; + + default: + return KErrNotSupported; + }; + + TInt irq=__SPIN_LOCK_IRQSAVE(I2sLock); // seems that we must guarantee the following sequence is uninterrupted + // before changing FSCLKSEL and/or FSMODE - mask I2S bit + // MSK_I2Sx (x=0:3): bits 18:21 in MaskCtrl Register of the System Ctrl Unit + AsspRegister::Modify32(KHwBaseSCU + KHoSCUClockMaskCtrl, 0, (1<1) + { + if ( aThreshold!=(aThreshold & i)) + break; + i>>=1; + } + aThreshold = i+1; //this will now contain one of possible values (2-16); + + // now any of 16/8/4/2, shifted right until == 0 will give us requested register_value+2 + // (instead of using 'switch(aThreshold)') + i=0; + while(aThreshold) + { + aThreshold>>=1; + ++i; + } + aThreshold = i-2 >= 0 ? i-2 : 0; //if i-2 gives <0 (e.g.for aThreshold<4) -adjust to 0; + + if (AsspIsBitSet(KHwI2SControl(iInterfaceId), KHtI2SCtrl_TEN | KHtI2SCtrl_REN)) + { + return KErrInUse; + } + + TUint32 clr, set; + if(aDirection & I2s::ERx) // receive fifo.. + { + if (aFramePhase == I2s::ELeft) + { + clr = CLEARMASK(KHsI2SFifoCtrl_RFIFOLT, 3); + set = (aThreshold << KHsI2SFifoCtrl_RFIFOLT); + } + + else //if (aFramePhase == I2s::ERight) + { + clr = CLEARMASK(KHsI2SFifoCtrl_RFIFORT, 3); + set = (aThreshold << KHsI2SFifoCtrl_RFIFORT); + } + } + else // transmit fifo.. + { + if (aFramePhase == I2s::ELeft) + { + clr = CLEARMASK(KHsI2SFifoCtrl_TFIFOLT, 3); + set = (aThreshold << KHsI2SFifoCtrl_TFIFOLT); + + } + else // if (aFramePhase == I2s::ERight) + { + clr = CLEARMASK(KHsI2SFifoCtrl_TFIFORT, 3); + set = (aThreshold << KHsI2SFifoCtrl_TFIFORT); + } + } + // updating register with value will also clear FIFO initialization bits.. + AsspRegister::Modify32(KHwI2SFifoControl(iInterfaceId), clr, set); + + return KErrNone; + } + +TInt D2sChannelNE1_TB::ReadFIFOModeStatus(TInt aFramePhase, TInt& aFlags) + { + aFlags = 0; + + TInt irq=__SPIN_LOCK_IRQSAVE(I2sLock); // (read and clear), can be used in ISR + TUint32 flags = AsspRegister::Read32(KHwI2SInterruptFlag(iInterfaceId)); + AsspRegister::Write32(KHwI2SInterruptFlag(iInterfaceId), flags); // clear the status flags (after reading) + __SPIN_UNLOCK_IRQRESTORE(I2sLock,irq); + + if (aFramePhase == I2s::ELeft) + { + if(flags & KHtI2SIntFlg_TFLURINT) // L-ch transmit FIFO underrun + aFlags |= I2s::ETxUnderrun; + + if(flags & KHtI2SIntFlg_TFLEINT) // L-ch transmit FIFO reached the empty trigger level + aFlags |= I2s::ETxEmpty; + + if(flags & KHtI2SIntFlg_RFLORINT) // L-ch receive FIFO overrun + aFlags |= I2s::ERxOverrun; + + if(flags & KHtI2SIntFlg_RFLFINT) // L-ch receive FIFO reached the full trigger level + aFlags |= I2s::ERxFull; + } + else + { + if(flags & KHtI2SIntFlg_TFRURINT) // R-ch transmit FIFO underrun + aFlags |= I2s::ETxUnderrun; + + if(flags & KHtI2SIntFlg_TFREINT) // R-ch transmit FIFO reached the empty trigger level + aFlags |= I2s::ETxEmpty; + + if(flags & KHtI2SIntFlg_RFRORINT) // R-ch receive FIFO overrun + aFlags |= I2s::ERxOverrun; + + if(flags & KHtI2SIntFlg_RFRFINT) // R-ch receive FIFO reached the full trigger level + aFlags |= I2s::ERxFull; + } + + return KErrNone; + } + +TInt D2sChannelNE1_TB::EnableFIFOInterrupts(TInt aFramePhase, TInt aInterrupt) + { + TUint32 val=0; + + if(aInterrupt & I2s::ERxFull) + { + if (aFramePhase == I2s::ELeft) + val |= KHtI2SIntMask_RFLFINT; + + if (aFramePhase == I2s::ERight) + val |= KHtI2SIntMask_RFRFINT; + } + + if(aInterrupt & I2s::ETxEmpty) + { + if (aFramePhase == I2s::ELeft) + val |= KHtI2SIntMask_TFLEINT; + + if (aFramePhase == I2s::ERight) + val |= KHtI2SIntMask_TFREINT; + } + + if(aInterrupt & I2s::ERxOverrun) + { + if (aFramePhase == I2s::ELeft) + val |= KHtI2SIntMask_RFLORINT; + + if (aFramePhase == I2s::ERight) + val |= KHtI2SIntMask_RFRORINT; + } + + if(aInterrupt & I2s::ETxUnderrun) + { + if (aFramePhase == I2s::ELeft) + val |= KHtI2SIntMask_TFLURINT; + + if (aFramePhase == I2s::ERight) + val |= KHtI2SIntMask_TFRURINT; + } + + if(aInterrupt & I2s::EFramingError) + { + // not supported, do nothing + } + + if (val) + { + // update the register + AsspRegister::Write32(KHwI2SInterruptMask(iInterfaceId), val); + } + + return KErrNone; + } + +TInt D2sChannelNE1_TB::DisableFIFOInterrupts(TInt aFramePhase, TInt aInterrupt) + { + TUint32 val = KHmI2SIntMask_ALL; + + if(aInterrupt & I2s::ERxFull) + { + if (aFramePhase == I2s::ELeft) + val &= ~KHtI2SIntMask_RFLFINT; + + if (aFramePhase == I2s::ERight) + val &= ~KHtI2SIntMask_RFRFINT; + } + + if(aInterrupt & I2s::ETxEmpty) + { + if (aFramePhase == I2s::ELeft) + val &= ~KHtI2SIntMask_TFLEINT; + + if (aFramePhase == I2s::ERight) + val &= ~KHtI2SIntMask_TFREINT; + } + + if(aInterrupt & I2s::ERxOverrun) + { + if (aFramePhase == I2s::ELeft) + val &= ~KHtI2SIntMask_RFLORINT; + + if (aFramePhase == I2s::ERight) + val &= ~KHtI2SIntMask_RFRORINT; + } + + if(aInterrupt & I2s::ETxUnderrun) + { + if (aFramePhase == I2s::ELeft) + val &= ~KHtI2SIntMask_TFLURINT; + + if (aFramePhase == I2s::ERight) + val &= ~KHtI2SIntMask_TFRURINT; + } + + if(aInterrupt & I2s::EFramingError) + { + // not supported, do nothing + } + + TInt irq=__SPIN_LOCK_IRQSAVE(I2sLock); // (read and clear), not used from ISR but made safe nevertheless... + TUint32 oldVal = AsspRegister::Read32(KHwI2SInterruptMask(iInterfaceId)); + if (val!=oldVal) + { + // update the register + AsspRegister::Write32(KHwI2SInterruptMask(iInterfaceId), val); + } + __SPIN_UNLOCK_IRQRESTORE(I2sLock,irq); + + return KErrNone; + } + +TInt D2sChannelNE1_TB::IsFIFOInterruptEnabled(TInt aFramePhase, TInt& aEnabled) + { + // check, if any interrupt is enabled.. + TUint32 val = AsspRegister::Read32(KHwI2SInterruptMask(iInterfaceId)); + + aEnabled=0; + if(aFramePhase== I2s::ELeft) + { + if(val & KHtI2SIntMask_TFLURINT)// L-ch transmit FIFO underrun int enable + aEnabled |= I2s::ETxUnderrun; + if(val & KHtI2SIntMask_TFLEINT)// L-ch transmit FIFO reached the empty trigger level int enable + aEnabled |= I2s::ETxEmpty; + if(val & KHtI2SIntMask_RFLORINT)// L-ch receive FIFO overrun int enable + aEnabled |= I2s::ERxOverrun; + if(val & KHtI2SIntMask_RFLFINT)// L-ch receive FIFO reached the full trigger level int enable + aEnabled |= I2s::ERxFull; + } + else + { + if(val & KHtI2SIntMask_TFRURINT)// R-ch transmit FIFO underrun int enable + aEnabled |= I2s::ETxUnderrun; + if(val & KHtI2SIntMask_TFREINT)// R-ch transmit FIFO reached the empty trigger level int enable + aEnabled |= I2s::ETxEmpty; + if(val & KHtI2SIntMask_RFRORINT)// R-ch receive FIFO overrun int enable + aEnabled |= I2s::ERxOverrun; + if(val & KHtI2SIntMask_RFRFINT)// R-ch receive FIFO reached the full trigger level int enable + aEnabled |= I2s::ERxFull; + } + + return KErrNone; + } + +TInt D2sChannelNE1_TB::ReadFIFOLevel(TInt aFramePhase, TInt aDirection, TInt& aLevel) + { + // This device only allows us to see, if the receive FIFO or transmit FIFO is either + // empty or full, so return: + // TX FIFO: 1-FULL, 0-EMPTY, + // RX FIFO: 1-EMPTY, 0-FULL + + TUint32 val = AsspRegister::Read32(KHwI2SFifoStatus(iInterfaceId)); + + if(aDirection & I2s::ETx) + { + if (aFramePhase == I2s::ELeft) + { + aLevel = (val & KHtI2SFifoSts_TFL_FULL) >> 17; // L-ch transmit FIFO full (bit 17) + } + else // I2s::ERight + { + aLevel = (val & KHtI2SFifoSts_TFR_FULL) >> 16; // R-ch transmit FIFO full (bit 16) + } + } + else // I2s::ERx + { + if (aFramePhase == I2s::ELeft) + { + aLevel = (val & KHtI2SFifoSts_RFL_EMPTY) >> 1; // L-ch receive FIFO empty (bit 1) + } + else // I2s::ERight + { + aLevel = val & KHtI2SFifoSts_RFR_EMPTY; // R-ch receive FIFO empty (bit 0) + } + } + + return KErrNone; + } + +TInt D2sChannelNE1_TB::EnableDMA(TInt aFifoMask) + { + TUint32 val=0; + + if(aFifoMask & I2s::ETx) + val |= KHtI2SFifoCtrl_TDMAEN; + + if(aFifoMask & I2s::ERx) + val |= KHtI2SFifoCtrl_RDMAEN; + + AsspRegister::Modify32(KHwI2SFifoControl(iInterfaceId), 0, val); + + return KErrNone; + } + +TInt D2sChannelNE1_TB::DisableDMA(TInt aFifoMask) + { + TUint32 val=0; + + if(aFifoMask & I2s::ETx) + val |= KHtI2SFifoCtrl_TDMAEN; + + if(aFifoMask & I2s::ERx) + val |= KHtI2SFifoCtrl_RDMAEN; + + AsspRegister::Modify32(KHwI2SFifoControl(iInterfaceId), val, 0); + + return KErrNone; + } + +TInt D2sChannelNE1_TB::IsDMAEnabled(TInt& aEnabled) + { + TUint32 val = AsspRegister::Read32(KHwI2SFifoControl(iInterfaceId)); + aEnabled = 0; + + if(val & KHtI2SFifoCtrl_TDMAEN) + aEnabled |= I2s::ETx; + + if(val & KHtI2SFifoCtrl_RDMAEN) + aEnabled |= I2s::ERx; + + return KErrNone; + } + +TInt D2sChannelNE1_TB::Start(TInt aDirection) + { + TUint32 val=0; + + if(aDirection & I2s::ERx) + { + // check, if the interface was configured for reception.. + if (iConfig.iType != I2s::EReceiver && iConfig.iType != I2s::EBidirectional) + { + return KErrNotSupported; + } + + __KTRACE_OPT(KDLL, Kern::Printf("I2S channel %d: Start Rx", iInterfaceId)); + val |= KHtI2SCtrl_REN; + } + else + { + // check, if the interface was configured for transmission.. + if (iConfig.iType != I2s::ETransmitter && iConfig.iType != I2s::EBidirectional) + { + return KErrNotSupported; + } + + __KTRACE_OPT(KDLL, Kern::Printf("I2S channel %d: Start Tx", iInterfaceId)); + val |= KHtI2SCtrl_TEN; + } + + // update the register + AsspRegister::Modify32(KHwI2SControl(iInterfaceId), 0, val); + + return KErrNone; + } + +TInt D2sChannelNE1_TB::Stop(TInt aDirection) + { + TUint32 val=0; + + if(aDirection & I2s::ERx) + { + __KTRACE_OPT(KDLL, Kern::Printf("I2S channel %d: Stop Rx", iInterfaceId)); + val = KHtI2SCtrl_REN; + } + else + { + __KTRACE_OPT(KDLL, Kern::Printf("I2S channel %d: Stop Rx", iInterfaceId)); + val = KHtI2SCtrl_TEN; + } + + // update the register + AsspRegister::Modify32(KHwI2SControl(iInterfaceId), val, 0); + + return KErrNone; + } + +TInt D2sChannelNE1_TB::IsStarted(TInt aDirection, TBool& aStarted) + { + TUint32 val=AsspRegister::Read32(KHwI2SControl(iInterfaceId)); + + if(aDirection & I2s::ERx) + { + aStarted = (val & KHtI2SCtrl_REN) >> 24; // bit 24 + } + else + { + aStarted = (val & KHtI2SCtrl_TEN) >> 25; // bit 25 + } + return KErrNone; + } + + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/interrupts.cia --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/interrupts.cia Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\interrupts.cia +* +*/ + + + +#include + +#ifndef __SMP__ +__NAKED__ void NaviEngineInterrupt::IrqDispatch() + { + asm("stmfd sp!, {r4,r5,lr}"); + asm("ldr r4, __KHwBaseIntIf"); // Base address of Interrupt interface + asm("ldr r12, __Handlers"); // Base address of interrupt handlers + + + asm("ldr r5, [r4, #%a0]" : : "i" ((TInt)KHoCIIIntAck)); // Acknowledge the interrupt + + asm("ldr lr, __KHmIntMask"); // Interrupt mask in end-of-interrupt register + asm("and r5, r5, lr"); // r5 = interruptID + + asm("cmp r5, lr"); // Spurious interrupt has ID 1023 + asm("beq IRQ_End"); + + // Call handler + asm("add r12, r12, r5, lsl #3"); + asm("adr lr, IRQ_End"); + asm("ldmia r12, {r0, pc}"); // Call interrupt handler. This will alse clear interrupt cause. + + // End of Interrupt + asm("IRQ_End:"); + asm("str r5, [r4, #%a0]" : : "i" ((TInt)KHoCIIEndOfInt)); + asm("ldmfd sp!, {r4,r5,pc}"); // No more pending, so finish + + asm("__KHwBaseIntIf:"); + asm(".word %a0" : : "i" ((TInt)KHwBaseIntIf)); + asm("__Handlers: "); + asm(".word %a0" : : "i" ((TInt)&NaviEngineInterrupt::Handlers[0])); + asm("__KHmIntMask:"); + asm(".word %a0" : : "i" ((TInt)1023)); + } +#endif + +//FIQ is not used, so this should never be called. +__NAKED__ void NaviEngineInterrupt::FiqDispatch() + { + asm("mov r0, #0"); + asm("sub r0, r0, #1"); // r0 = -1 + asm("str r0, [r0]"); // Generate exception + } diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/interrupts.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/interrupts.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,352 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\interrupts.cpp +* NE1_TBVariant ASSP interrupt control and dispatch +* +*/ + + + +#include + +const TUint8 IntIsEdge[96] = + { + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + +#ifdef __SMP__ +#include + +#ifndef __STANDALONE_NANOKERNEL__ +#undef DEBUGPRINT +#define DEBUGPRINT Kern::Printf +#endif + +TUint32 NaviEngineInterrupt::IrqDispatch(TUint32 aVector) + { + if (aVector<32 || aVector>127) + { + GicCpuIfc& g = *(GicCpuIfc*)KHwBaseIntIf; + g.iEoi = aVector; + *(TInt*)0xdeaddead = 0; + return aVector; + } + NKern::Interrupt(aVector - 32); + return aVector; + } + +void NaviEngineInterrupt::DisableAndClearAll() + { + // NKern does all the GIC stuff + } + +void NaviEngineInterrupt::Init1() + { + __KTRACE_OPT(KBOOT, DEBUGPRINT(">Interrupt_Init1()")); + DisableAndClearAll(); + Arm::SetIrqHandler((TLinAddr)&IrqDispatch); + Arm::SetFiqHandler((TLinAddr)&FiqDispatch); + TInt i; + for (i=32; i<128; ++i) + { + TBool edge = IntIsEdge[i-32]; + TUint32 flags = 0; + if (i>=36 && i<42) + flags |= NKern::EIrqInit_Count; // timers count all interrupts + if (edge) + flags |= NKern::EIrqInit_RisingEdge; + else + flags |= NKern::EIrqInit_LevelHigh; + TInt r = NKern::InterruptInit(i-32, flags, i, i); + __KTRACE_OPT(KBOOT, DEBUGPRINT("InterruptInit %d(%02x) -> %d", i-32, i, r)); + __NK_ASSERT_ALWAYS(r==KErrNone); + } + + __KTRACE_OPT(KBOOT, DEBUGPRINT("=(TUint)KNumNaviEngineInts) + return KErrArgument; + TUint32 flags = 0; + if (id>=36 && id<=41) + { + flags |= NKern::EIrqBind_Count; + } + return NKern::InterruptBind(id-32, aIsr, aPtr, flags, 0); + } + +EXPORT_C TInt Interrupt::Unbind(TInt aId) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Interrupt::Unbind id=%08x",aId)); + if (aId >= 0x10000) + return NKern::InterruptUnbind(aId); // aId is a handle not a specific ID + if (TUint(aId) < TUint(KNumNaviEngineMaxInts)) + return NKern::InterruptUnbind(aId - 32); // Vector number to nanokernel interrupt number + return KErrArgument; + } + +EXPORT_C TInt Interrupt::Enable(TInt aId) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Interrupt::Enable id=%08x",aId)); + if (aId >= 0x10000) + return NKern::InterruptEnable(aId); // aId is a handle not a specific ID + if (TUint(aId) < TUint(KNumNaviEngineMaxInts)) + return NKern::InterruptEnable(aId - 32); // Vector number to nanokernel interrupt number + return KErrArgument; + } + +EXPORT_C TInt Interrupt::Disable(TInt aId) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Interrupt::Disable id=%08x",aId)); + if (aId >= 0x10000) + return NKern::InterruptDisable(aId); // aId is a handle not a specific ID + if (TUint(aId) < TUint(KNumNaviEngineMaxInts)) + return NKern::InterruptDisable(aId - 32); // Vector number to nanokernel interrupt number + return KErrArgument; + } + +EXPORT_C TInt Interrupt::Clear(TInt aId) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Interrupt::Clear id=%08x",aId)); + if (aId >= 0x10000) + return NKern::InterruptClear(aId); // aId is a handle not a specific ID + if (TUint(aId) < TUint(KNumNaviEngineMaxInts)) + return NKern::InterruptClear(aId - 32); // Vector number to nanokernel interrupt number + return KErrArgument; + } + +EXPORT_C TInt Interrupt::SetPriority(TInt /*anId*/, TInt /*aPriority*/) + { + return KErrNotSupported; + } + +#else +SInterruptHandler NaviEngineInterrupt::Handlers[KNumNaviEngineInts]; + +void NaviEngineInterrupt::DisableAndClearAll() + { + //Disable all interrupts + for(TUint i=0; i<=((KNumNaviEngineInts-1)/32); i++) + AsspRegister::Write32(KHoGidIntDisableBase+i*4, 0xffffffff); + //Clear all interrupts + for(TUint i=0; i<=((KNumNaviEngineInts-1)/32); i++) + AsspRegister::Write32(KHoGidPendClearBase+i*4, 0xffffffff); + + } + +void NaviEngineInterrupt::Init1() + { + // + // need to hook the ARM IRQ and FIQ handlers as early as possible and disable and clear all interrupt sources + // + __KTRACE_OPT(KBOOT,Kern::Printf("NaviEngineInterrupt::Init1()")); + TInt i; + for (i=0; i=32 && i<128) + { + isEdge = IntIsEdge[i-32]; + } + const TUint8 isNN = 0x1; + const TUint8 irqConfig = (isEdge << 1) | isNN; + + const TInt byteOffset = i/4; + const TInt shiftForIrq = i%4; + TUint8 setMask = irqConfig << shiftForIrq; + AsspRegister::Modify8(KHoGidConfigBase + byteOffset, 0, setMask); + } + + // Set interrupts starting from 32 to this CPU only + for(TUint i=0; i<=((KNumNaviEngineInts-1)/4); i++) + AsspRegister::Write32(KHoGidTargetBase+i*4, 0x0f0f0f0f); + + // Set priority on all interrupts + for(TUint i=0; i<=((KNumNaviEngineInts-1)/4); i++) + AsspRegister::Write32(KHoGidPriorityBase+i*4, 0xA0A0A0A0); + + // Set binary point. No-preemption, all bits used + AsspRegister::Write32(KHwCIIBinPoint, 7); + + // Set priority mask + AsspRegister::Write32(KHwCIIPrioMask, 0xF0); + + // Enable Distributor and CPU Interface for IRQ + AsspRegister::Write32(KHoGidControl, 1); + AsspRegister::Write32(KHwCIIControl, 1); + } + +void NaviEngineInterrupt::Init3() + { + // + // Any further initialisation of the Hardware Interrupt Controller + // Note This is not called at the moment. Should be deleted. + } + +void NaviEngineInterrupt::Spurious(TAny* anId) + { + Kern::Fault("SpuriousInt", (TInt)anId); + } + +// +// The APIs below assume ther is a second level Interrupt controller located at Variant level which handles +// interrupts generated by hardware at that level. +// + +EXPORT_C TInt Interrupt::Bind(TInt anId, TIsr anIsr, TAny* aPtr) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Interrupt::Bind id=%d func=%08x ptr=%08x",anId,anIsr,aPtr)); + TInt r = anId; + // if ID indicates a chained interrupt, call variant... +// if (anId<0 && ((((TUint)anId)>>16)&0x7fff)<(TUint)KNumNaviEngineInts) +// r=NaviEngineAssp::Variant->InterruptBind(anId,anIsr,aPtr); + __NK_ASSERT_ALWAYS(anId>=0); + if ((TUint)anId >= (TUint)KNumNaviEngineInts) + r=KErrArgument; + else + { + SInterruptHandler& h=NaviEngineInterrupt::Handlers[anId]; + TInt irq=NKern::DisableAllInterrupts(); + if (h.iIsr != NaviEngineInterrupt::Spurious) + r=KErrInUse; + else + { + h.iPtr=aPtr; + h.iIsr=anIsr; + } + NKern::RestoreInterrupts(irq); + } + return r; + } + +EXPORT_C TInt Interrupt::Unbind(TInt anId) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Interrupt::Unbind id=%d",anId)); + TInt r=KErrNone; + // if ID indicates a chained interrupt, call variant... + if (anId<0 && ((((TUint)anId)>>16)&0x7fff)<(TUint)KNumNaviEngineInts) + r=NaviEngineAssp::Variant->InterruptUnbind(anId); + else if ((TUint)anId >= (TUint)KNumNaviEngineInts) + r=KErrArgument; + else + { + SInterruptHandler& h=NaviEngineInterrupt::Handlers[anId]; + TInt irq=NKern::DisableAllInterrupts(); + if (h.iIsr == NaviEngineInterrupt::Spurious) + r=KErrGeneral; + else + { + h.iPtr=(TAny*)anId; + h.iIsr=NaviEngineInterrupt::Spurious; + Disable(anId); + } + NKern::RestoreInterrupts(irq); + } + return r; + } + +EXPORT_C TInt Interrupt::Enable(TInt anId) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Interrupt::Enable id=%d",anId)); + TInt r=KErrNone; + // if ID indicates a chained interrupt, call variant... + if (anId<0 && ((((TUint)anId)>>16)&0x7fff)<(TUint)KNumNaviEngineInts) + r=NaviEngineAssp::Variant->InterruptEnable(anId); + else if ((TUint)anId>=(TUint)KNumNaviEngineInts) + r=KErrArgument; + else if (NaviEngineInterrupt::Handlers[anId].iIsr==NaviEngineInterrupt::Spurious) + r=KErrNotReady; + else + { + TUint reg = anId/32; + TUint mask = 1 << (anId - 32*reg); + AsspRegister::Write32(KHoGidIntEnableBase+reg*4, mask); + } + return r; + } + +EXPORT_C TInt Interrupt::Disable(TInt anId) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Interrupt::Disable id=%d",anId)); + TInt r=KErrNone; + // if ID indicates a chained interrupt, call variant... + if (anId<0 && ((((TUint)anId)>>16)&0x7fff)<(TUint)KNumNaviEngineInts) + r=NaviEngineAssp::Variant->InterruptDisable(anId); + else if ((TUint)anId>=(TUint)KNumNaviEngineInts) + r=KErrArgument; + else + { + TUint reg = anId/32; + TUint mask = 1 << (anId - 32*reg); + AsspRegister::Write32(KHoGidIntDisableBase+reg*4, mask); + } + return r; + } + +EXPORT_C TInt Interrupt::Clear(TInt anId) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Interrupt::Clear id=%d",anId)); + TInt r=KErrNone; + // if ID indicates a chained interrupt, call variant... + if (anId<0 && ((((TUint)anId)>>16)&0x7fff)<(TUint)KNumNaviEngineInts) + r=NaviEngineAssp::Variant->InterruptClear(anId); + else if ((TUint)anId>=(TUint)KNumNaviEngineInts) + r=KErrArgument; + else + { + TUint reg = anId/32; + TUint mask = 1 << (anId - 32*reg); + AsspRegister::Write32(KHoGidPendClearBase+reg*4, mask); + } + return r; + } + +EXPORT_C TInt Interrupt::SetPriority(TInt /*anId*/, TInt /*aPriority*/) + { + return KErrNotSupported; + } +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/kanaviengine.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/kanaviengine.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp/kanaviengine.mmp +* +*/ + + + +#include +#include "kernel/kern_ext.mmh" + +USERINCLUDE . +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + +target VariantTarget(kanaviengine,dll) +targettype kext +linkas kanaviengine.dll + +// if this macro is on, the tick interrupt will toggle the UART1 DTR line. +// If uart1, or the pin, is required for another purpose comment this out +// only used internally for idle thread debugging +// macro TOGLE_UART_DTR_LINE + +//source naviengine_assp.cpp interrupts.cpp assp.cpp register.cpp gpio.cpp +source naviengine_assp.cpp interrupts.cpp assp.cpp register.cpp +source naviengine_assp.cia interrupts.cia assp.cia + + +deffile ./~/kanaviengine.def + +nostrictdef + +epocallowdlldata + +uid 0x1000008d 0x100000b9 + +VENDORID 0x70000001 + +capability all + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/lcdgce/lcdgce.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/lcdgce/lcdgce.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,1841 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* \hwip_nec_naviengine\naviengine_assp\lcdgce\lcdgce.cpp +* Implementation of an LCD driver with GCE support. +* This file is part of the NE1_TBVariant Base port +* N.B. This sample code assumes that the display supports setting the backlight on or off, +* as well as adjusting the contrast and the brightness. +* +*/ + + + +/** + @file Implementation of an LCD driver with GCE support. + @internalTechnology + @prototype +*/ + +#include +#include "platform.h" +#include +#include +#include +#include +#include +#include "lcdgce.h" +#include +#include "powerresources.h" +#include + +// define the characteristics of the LCD display +// This is only example code... you need to modify it for your hardware +const TBool KConfigLcdIsMono = EFalse; +const TBool KConfigLcdPixelOrderLandscape = ETrue; +const TBool KConfigLcdPixelOrderRGB = ETrue; +const TInt KConfigLcdMaxDisplayColors = 65536; +const TUint32 KShiftBitsPerByte = 3; +const TInt KConfigBitsPerPixel16 = 16; +const TInt KConfigBitsPerPixel32 = 32; + +#define RESOLUTION_AND_CYCLE DISPLAY_RESOLUTION_AND_CYCLE(Lcd_Mode_Config[iInitialMode].iConfigLcdHeight, Lcd_Mode_Config[iInitialMode].iConfigLcdWidth, Lcd_Mode_Config[iInitialMode].iLinesInFrame, Lcd_Mode_Config[iInitialMode].iPixelsInLine) + +#define SCREEN_UNIT 0 +#define SCREEN_UNIT_COUNT 1 + +struct SLcdConfig + { + TInt iOffsetToFirstVideoBuffer; + TInt iConfigLcdWidth; // The width of the physical display + TInt iConfigLcdHeight; // The height of the physical display + TBool iIsPalettized; + TInt iBitsPerPixel; + TUint64 iPulseWidth; + TUint iLinesInFrame; // This appears to be a magic number that has no resemblence to the height + TUint iPixelsInLine; // This appears to be a magic number that has no resemblence to the width + TInt iReportedLcdWidth; // The width reported to the higher levels of software + TInt iReportedLcdHeight; // The height reported to the higher levels of software + }; + +static const SLcdConfig Lcd_Mode_Config[]= + { + // 0: DISPLAY_MODE_ANALOG_VGA: No LCD, Landscape VGA 640x480 + { 0, 640, 480, EFalse, KConfigBitsPerPixel32, KPulseWidthVga, 525, 800, 640, 480, }, + // 1: DISPLAY_MODE_HITACHI_VGA: Hitachi LCD, Portrait VGA 480x640 (for this mode, SW4-1 should be turned OFF on the LCD panel) + { 0, 480, 640, EFalse, KConfigBitsPerPixel32, KPulseWidthVgaLCD, 650, 650, 480, 640, }, + // 2: DISPLAY_MODE_ANALOG_QVGA_LANDSCAPE_OLD: No LCD, Landscape QVGA 320x240 + { 0, 320, 240, EFalse, KConfigBitsPerPixel32, KPulseWidthVga, 525, 800, 320, 240, }, + // 3: DISPLAY_MODE_HITACHI_QVGA: Hitachi LCD, Portrait QVGA 240x320 + { 0, 240, 320, EFalse, KConfigBitsPerPixel32, KPulseWidth, 525, 800, 240, 320, }, + // 4: DISPLAY_MODE_NEC_WVGA: NEC LCD, Landscape WVGA + { 0, 800, 480, EFalse, KConfigBitsPerPixel32, KPulseWidthWvga, 525, 1024, 800, 480, }, + // 5: DISPLAY_MODE_ANALOG_QVGA_PORTRAIT: No LCD, Portrait QVGA 240x320 + // Note! this screen mode reports different dimensions than the real panel size + { 0, 640, 480, EFalse, KConfigBitsPerPixel16, KPulseWidthVga, 525, 800, 240, 320, }, + // 6: DISPLAY_MODE_ANALOG_QVGA_LANDSCAPE: No LCD, Landscape QVGA 320x240 + { 0, 640, 480, EFalse, KConfigBitsPerPixel16, KPulseWidthVga, 525, 800, 320, 240, }, + }; + +// Hack function to convert pixels to TWIPS +// Twips are screen-independent units to ensure that the proportion of screen elements +// are the same on all display systems. A twip is defined as being 1/20th of a point. +inline TInt PixelsToTwips(TInt aPixels) + { + return (119*aPixels)/10; + } + +DLcdPowerHandler * DLcdPowerHandler::pLcd = NULL; + + +const TInt KDisplay0ThreadPriority = 26; + +const TInt KVSyncDfcPriority = 7 ; //priority of DFC within the queue (0 to 7, where 7 is highest) + + +_LIT(KLitLcd,"LCD"); +_LIT(KDisplay0DfcThread,"Display0DfcThread-"); + +TInt vsync_irq_callback(TUint a, TAny* b); + +#ifdef __SMP__ +static TSpinLock callbackLock = TSpinLock(TSpinLock::EOrderGenericIrqHigh0); +#endif + + +/********************************************** +* Class DDisplayPddNaviEng +***********************************************/ + +void DDisplayPddNaviEng::VSyncDfcFn(TAny* aChannel) + { + DDisplayPddNaviEng * channel =(DDisplayPddNaviEng*)aChannel; + + if (channel->iPostFlag) + { + channel->iPostFlag = EFalse; + + + if (channel->iActiveBuffer) + { + //When a User buffer is registered its iFree member becomes EFalse and Deregister sets it + //back to ETrue. Composition and Legacy buffers are not free when they are in the pending or + //active state. + if (channel->iActiveBuffer->iType == EBufferTypeUser) + { + //If a subsequent PostUserRequest has occured,so there is a pending user buffer which has + //cancelled the previous post( the one that queued the current active buffer), calling + //RequestComplete would mistakenly complete the latest PostUserRequest. + + if (!(channel->iPendingBuffer && channel->iPendingBuffer->iType == EBufferTypeUser) ) + { + channel->RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrNone); + } + + } + else + { + channel->iActiveBuffer->iFree = ETrue; + } + + channel->iActiveBuffer->iState = EBufferFree; + + + if (channel->iActiveBuffer->iType == EBufferTypeComposition) + { + //If no buffer was available during a call to GetCompositionBuffer the active buffer has + //been returned as the next available one, so we must set the buffer to the proper state before we + //send the notification. + TInt pendingIndex = channel->iLdd->iPendingIndex[RDisplayChannel::EReqGetCompositionBuffer]; + if( channel->iLdd->iPendingReq[RDisplayChannel::EReqGetCompositionBuffer][pendingIndex].iTClientReq) + { + if(channel->iLdd->iPendingReq[RDisplayChannel::EReqGetCompositionBuffer][pendingIndex].iTClientReq->IsReady() ) + { + channel->iActiveBuffer->iState = EBufferCompose; + channel->RequestComplete(RDisplayChannel::EReqGetCompositionBuffer, KErrNone); + } + } + } + + channel->iActiveBuffer = NULL; + } + + if (channel->iPendingBuffer) + { + __GCE_DEBUG_PRINT2("DDisplayPddNaviEng::VSyncDfcFn moving pending buffer at address %08x to the active state\n", channel->iPendingBuffer->iAddress); + channel->iActiveBuffer = channel->iPendingBuffer; + channel->iActiveBuffer->iState = EBufferActive; + channel->iPendingBuffer = NULL; + + channel->RequestComplete(RDisplayChannel::EReqWaitForPost, KErrNone); + } + } + + } + + + +/** + Constructor +*/ +DDisplayPddNaviEng::DDisplayPddNaviEng(): + iPendingBuffer(NULL), + iActiveBuffer(NULL), + iChunk(NULL), + iLcdCallback(NULL), + iVSyncDfc(&VSyncDfcFn, this, KVSyncDfcPriority) + { + __GCE_DEBUG_PRINT("DDisplayPddNaviEng::DDisplayPddNaviEng\n"); + + iPostFlag = EFalse; + } + +/** + Destructor +*/ +DDisplayPddNaviEng::~DDisplayPddNaviEng() + { + __GCE_DEBUG_PRINT("DDisplayPddNaviEng::~DDisplayPddNaviEng() \n"); + + if(iLcdCallback) + { + DLcdPowerHandler::pLcd->DeRegisterCallback(iLcdCallback) ; + delete iLcdCallback; + iLcdCallback = NULL; + } + + //The DFC Queue is owned by DLcdPowerHandler so we shouldn't call Destroy() at this point. + if (iDfcQ) + { + iDfcQ=NULL; + } + + DChunk* chunk = (DChunk*) __e32_atomic_swp_ord_ptr(&iChunk, 0); + + if(chunk) + { + Kern::ChunkClose(chunk); + } + + } + + +/** + Called by the LDD's DoCreate function to handle the device specific part of opening the channel. + (DoCreate is called by RDisplayChannel::Open) + + @param aUnit The screen unit + + @return KErrNone if successful; or one of the other system wide error codes. +*/ +TInt DDisplayPddNaviEng::CreateChannelSetup(TInt aUnit) + { + __GCE_DEBUG_PRINT("DDisplayPddNaviEng::CreateChannelSetup\n"); + + iScreenInfo = DLcdPowerHandler::pLcd->iVideoInfo; + iLdd->iUnit = aUnit; + + iLdd->iDisplayInfo.iAvailableRotations = RDisplayChannel::ERotationNormal; + iLdd->iDisplayInfo.iNormal.iOffsetBetweenLines = iScreenInfo.iOffsetBetweenLines; + iLdd->iDisplayInfo.iNormal.iHeight = iScreenInfo.iSizeInPixels.iHeight; + iLdd->iDisplayInfo.iNormal.iWidth = iScreenInfo.iSizeInPixels.iWidth; + iLdd->iDisplayInfo.iNumCompositionBuffers = KDisplayCBMax; + iLdd->iDisplayInfo.iBitsPerPixel = iScreenInfo.iBitsPerPixel; + iLdd->iDisplayInfo.iRefreshRateHz = 60; + + + switch (iScreenInfo.iBitsPerPixel) + { + case 16: + iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatRGB_565; + break; + case 24: + iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatRGB_888; + break; + case 32: + iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatARGB_8888; + break; + default: + iLdd->iDisplayInfo.iPixelFormat = EUidPixelFormatUnknown; + break; + } + + iLdd->iCurrentRotation = RDisplayChannel::ERotationNormal; + + // Open shared chunk to the composition framebuffer + + DChunk* chunk = 0; + TLinAddr chunkKernelAddr = 0; + TUint32 chunkMapAttr = 0; + + // round to twice the page size + TUint round = Kern::RoundToPageSize(2*DLcdPowerHandler::pLcd->iSize); + + __GCE_DEBUG_PRINT2("DDisplayPddNaviEng::CreateChannelSetup DLcdPowerHandler::pLcd->iSize = %d\n", DLcdPowerHandler::pLcd->iSize ); + + TChunkCreateInfo info; + info.iType = TChunkCreateInfo::ESharedKernelMultiple; + info.iMaxSize = round; + info.iMapAttr = EMapAttrFullyBlocking; + info.iOwnsMemory = EFalse; + info.iDestroyedDfc = 0; + + TInt r = Kern::ChunkCreate(info, chunk, chunkKernelAddr, chunkMapAttr); + + __GCE_DEBUG_PRINT2("CreateChannelSetup:ChunkCreate called for composition chunk. Set iChunkKernelAddr = %08x\n", chunkKernelAddr ); + + if( r == KErrNone) + { + // map our chunk + r = Kern::ChunkCommitPhysical(chunk, 0,round , DLcdPowerHandler::pLcd->iCompositionPhysical); + if(r != KErrNone) + { + Kern::ChunkClose(chunk); + } + } + + if ( r!= KErrNone) + { + return r; + } + + iChunk = chunk; + + // init CB 0 + iLdd->iCompositionBuffer[0].iType = EBufferTypeComposition; + iLdd->iCompositionBuffer[0].iBufferId = 0; + iLdd->iCompositionBuffer[0].iFree = ETrue; + iLdd->iCompositionBuffer[0].iState = EBufferFree; + iLdd->iCompositionBuffer[0].iAddress = chunkKernelAddr; + iLdd->iCompositionBuffer[0].iChunk = chunk; + iLdd->iCompositionBuffer[0].iHandle = 0; + iLdd->iCompositionBuffer[0].iOffset = 0; + iLdd->iCompositionBuffer[0].iSize = DLcdPowerHandler::pLcd->iSize; + iLdd->iCompositionBuffer[0].iPendingRequest = 0; + + // init CB 1 + iLdd->iCompositionBuffer[1].iType = EBufferTypeComposition; + iLdd->iCompositionBuffer[1].iBufferId = 1; + iLdd->iCompositionBuffer[1].iFree = ETrue; + iLdd->iCompositionBuffer[1].iState = EBufferFree; + iLdd->iCompositionBuffer[1].iAddress = chunkKernelAddr + DLcdPowerHandler::pLcd->iSize; + iLdd->iCompositionBuffer[1].iChunk = chunk; + iLdd->iCompositionBuffer[1].iHandle = 0; + iLdd->iCompositionBuffer[1].iOffset = DLcdPowerHandler::pLcd->iSize; + iLdd->iCompositionBuffer[1].iSize = DLcdPowerHandler::pLcd->iSize; + iLdd->iCompositionBuffer[1].iPendingRequest = 0; + + iLdd->iCompositionBuffIdx = 0; + + TUint64 reg64 = AsspRegister::Read64(KHwDisplayMemoryFrameAddress); + + //set up Start address for frames 0 and 1 (The actual Physical addresses must be passed) + AsspRegister::Write64(KHwDisplayMemoryFrameAddress , ( (TUint64)DLcdPowerHandler::pLcd->iCompositionPhysical<<32 | reg64 ) ); + + //set up layer 2 + TUint64 layer2Physical = DLcdPowerHandler::pLcd->iCompositionPhysical+ DLcdPowerHandler::pLcd->iSize ; + AsspRegister::Write64(KHwDisplayMemoryFrameAddress + KHex8,layer2Physical ) ; + + //Use the same DFC queue created by the DLcdPowerHandler so all hardware accesses are executed under the same DFC thread. + iDfcQ= DLcdPowerHandler::pLcd->iDfcQ; + + // Set the Post DFC. + iVSyncDfc.SetDfcQ(iDfcQ); + + //Register callback function. The function will be called when V Sync is triggered + iLcdCallback = new TLcdUserCallBack(vsync_irq_callback, (TAny*)this); + + r = KErrNoMemory; + if (iLcdCallback) + { + r = DLcdPowerHandler::pLcd->RegisterCallback(iLcdCallback) ; + } + + if( r!= KErrNone) + { + delete iLcdCallback ; + iLcdCallback = NULL ; + return r; + } + + return KErrNone; + } + + +/** + Called by the Vsync callback method and queues the corresponding DFC. + */ +void DDisplayPddNaviEng::VSyncIsr() + { + iVSyncDfc.Add(); + } + + +/** + Return the DFC queue to be used for this device. + */ +TDfcQue * DDisplayPddNaviEng:: DfcQ(TInt aUnit) + { + return iDfcQ; + } + + +/** + Handles device specific operations when a close message has been sent to the Logical Channel. + +*/ +TInt DDisplayPddNaviEng::CloseMsg() + { + __GCE_DEBUG_PRINT("DDisplayPddNaviEng::CloseMsg()\n"); + + iPendingBuffer = NULL; + iActiveBuffer = NULL; + + iVSyncDfc.Cancel(); + return KErrNone; + } + + +/** + Set the GCE mode by posting a composition buffer. + +*/ +TInt DDisplayPddNaviEng::SetGceMode() + { + __GCE_DEBUG_PRINT("DDisplayPddNaviEng::SetGceMode()\n"); + + PostCompositionBuffer(&iLdd->iCompositionBuffer[0]); + return KErrNone; + } + + +/** + Set the Legacy Mode by setting the appropriate Frame control value. + +*/ +TInt DDisplayPddNaviEng::SetLegacyMode() + { + __GCE_DEBUG_PRINT("DDisplayPddNaviEng::SetLegacyMode()\n"); + + //Set the default frame 0 which corresponds to the Legacy Buffer. + AsspRegister::Write64(KHwDisplayDisplayFrameControl, KDisplayFrameControlValue); + return KErrNone; + } + + +/** + If the specified rotation is supported set it as the current rotation. The NaviEngine + version supports only the RDisplayChannel::ERotationNormal rotation. + + @param aDegOfRot The requested rotation to be set. + + @return KErrNone if the rotation is supported else KErrArgument. +*/ +TInt DDisplayPddNaviEng::SetRotation(RDisplayChannel::TDisplayRotation aDegOfRot) + { + TInt r; + + switch (aDegOfRot) + { + case RDisplayChannel::ERotationNormal: + r = KErrNone; + break; + default: + r = KErrArgument; + } + + return r; + } + + +/** + Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization + with V Sync so it will take affect in the next V Sync after that) and also set the buffer provided as the buffer to + be posted next. Layer 3 is associated with user buffers. + + @param aNode Pointer to the User buffer to post. +*/ +TInt DDisplayPddNaviEng::PostUserBuffer(TBufferNode* aNode) + { + + __GCE_DEBUG_PRINT2("PostUserBuffer : aNode->iAddress = %08x\n", aNode->iAddress); + + if(iPendingBuffer) + { + iPendingBuffer->iState = EBufferFree; + if (!(iPendingBuffer->iType == EBufferTypeUser) ) + { + iPendingBuffer->iFree = ETrue; + } + } + + //Set the Physical address for layer3 and then set layer3 as the frame to be displayed. + AsspRegister::Write64(KHwDisplayMemoryFrameAddress + KHex8 ,(TUint64)aNode->iPhysicalAddress<<32 ); + AsspRegister::Write64(KHwDisplayDisplayFrameControl, KDisplayFrame3ControlValue); + + aNode->iState = EBufferPending; + iPendingBuffer = aNode; + iPostFlag = ETrue; + + TUint64 reg64 = AsspRegister::Read64(KHwDisplayInterruptEnable); + reg64 |= KVSyncEnable; + AsspRegister::Write64(KHwDisplayInterruptEnable , reg64 ); //Enable Vsync + + return KErrNone; + } + + +/** + Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization + with V Sync so it will take affect in the next V Sync after that) and also set the buffer provided as the buffer to + be posted next. Layer 1 and 2 are associated with composition buffers 0 and 1 respectively. + + @param aNode Pointer to the Composition buffer to post. +*/ +TInt DDisplayPddNaviEng::PostCompositionBuffer(TBufferNode* aNode) + { + + __GCE_DEBUG_PRINT2("PostCompositionBuffer : aNode->iAddress = %08x\n", aNode->iAddress); + + if(iPendingBuffer) + { + iPendingBuffer->iState = EBufferFree; + if (iPendingBuffer->iType == EBufferTypeUser) + { + RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrCancel); + } + else + { + iPendingBuffer->iFree = ETrue; + } + } + + if ( aNode->iBufferId == 0) + { + // Display frame control registers (Layer 1) + AsspRegister::Write64(KHwDisplayDisplayFrameControl , KDisplayFrame1ControlValue ); + } + else if ( aNode->iBufferId == 1) + { + // Display frame control registers (Layer 2) + AsspRegister::Write64(KHwDisplayDisplayFrameControl , KDisplayFrame2ControlValue); + + //Reset Layer2 ( The value might have been overwriten by a PostUserBuffer operation). + AsspRegister::Write64(KHwDisplayMemoryFrameAddress + KHex8, DLcdPowerHandler::pLcd->iCompositionPhysical + DLcdPowerHandler::pLcd->iSize); + } + + aNode->iState = EBufferPending; + aNode->iFree = EFalse; + iPendingBuffer = aNode; + iPostFlag = ETrue; + + TUint64 reg64 = AsspRegister::Read64(KHwDisplayInterruptEnable); + reg64 |= KVSyncEnable; + AsspRegister::Write64(KHwDisplayInterruptEnable , reg64 ); //Enable Vsync + + return KErrNone; + } + + +/** + Remove any previous post operations, set the appropriate layer as the next layer to be displayed( This value is updated in synchronization + with V Sync so it will take affect in the next V Sync after that) and also set the Legacy Buffer as the buffer to + be posted next.Layer 0 is associated with legacy buffer. + + @param aNode Pointer to the Composition buffer to post. +*/ +TInt DDisplayPddNaviEng::PostLegacyBuffer() + { + __GCE_DEBUG_PRINT("PostLegacyBuffer() \n"); + + if(iPendingBuffer) + { + iPendingBuffer->iState = EBufferFree; + if (iPendingBuffer->iType == EBufferTypeUser) + { + + RequestComplete(RDisplayChannel::EReqPostUserBuffer, KErrCancel); + } + else + { + iPendingBuffer->iFree = ETrue; + } + } + + + AsspRegister::Write64(KHwDisplayDisplayFrameControl, KDisplayFrameControlValue); + + iLdd->iLegacyBuffer[0].iState = EBufferPending; + iLdd->iLegacyBuffer[0].iFree = EFalse; + iPendingBuffer = &iLdd->iLegacyBuffer[0]; + iPostFlag = ETrue; + + TUint64 reg64 = AsspRegister::Read64(KHwDisplayInterruptEnable); + reg64 |= KVSyncEnable; + AsspRegister::Write64(KHwDisplayInterruptEnable , reg64 ); //Enable Vsync + + return KErrNone; + } + +/** +Detect whether a post operation is pending +*/ +TBool DDisplayPddNaviEng::PostPending() + { + return (iPendingBuffer != NULL); + } + +/** +VSync Callback function + */ +TInt vsync_irq_callback(TUint a, TAny* ch) + { + // get channel + if(ch) + { + DDisplayPddNaviEng * channel=(DDisplayPddNaviEng*)ch; + channel->VSyncIsr(); + } + return KErrNone; + } + + +//***************************************************************** +//DDisplayPddFactory +//*****************************************************************/ + + +/** + Constructor +*/ +DDisplayPddFactory::DDisplayPddFactory() + { + __GCE_DEBUG_PRINT("DDisplayPddFactory::DDisplayPddFactory()\n"); + + iVersion = TVersion(KDisplayChMajorVersionNumber, + KDisplayChMinorVersionNumber, + KDisplayChBuildVersionNumber); + } + +/** + PDD factory function. Creates a PDD object. + + @param aChannel A pointer to an PDD channel object which will be initialised on return. + + @return KErrNone if object successfully allocated, KErrNoMemory if not. +*/ +TInt DDisplayPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer) + { + DDisplayPddNaviEng *device= new DDisplayPddNaviEng() ; + aChannel=device; + if (!device) + { + return KErrNoMemory; + } + return KErrNone; + } + + +/** + Set the Pdd name and return error code +*/ +TInt DDisplayPddFactory::Install() + { + __GCE_DEBUG_PRINT("DDisplayPddFactory::Install() \n"); + + TBuf<32> name(RDisplayChannel::Name()); + _LIT(KPddExtension,".pdd"); + name.Append(KPddExtension); + return SetName(&name); + } + + +void DDisplayPddFactory::GetCaps(TDes8& /*aDes*/) const + { + //Not supported + } + + +/** + Validate version and number of units. +*/ +TInt DDisplayPddFactory::Validate(TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& aVer) + { + if (!Kern::QueryVersionSupported(iVersion,aVer)) + { + return KErrNotSupported; + } + + if (aUnit != 0) + { + return KErrNotSupported; + } + + return KErrNone; + } + +DECLARE_EXTENSION_PDD() +/** + "Standard PDD" entrypoint.Creates PDD factory when Kern::InstallPhysicalDevice is called + + @return pointer to the PDD factory object. +*/ + { + __GCE_DEBUG_PRINT("DECLARE_EXTENSION_PDD()\n"); + return new DDisplayPddFactory ; + } + + +/** +HAL handler function + +@param aPtr a pointer to an instance of DLcdPowerHandler +@param aFunction the function number +@param a1 an arbitrary parameter +@param a2 an arbitrary parameter +*/ +LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2) + { + DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr; + return pH->HalFunction(aFunction,a1,a2); + } + +/** +DFC for receiving messages from the power handler +@param aPtr a pointer to an instance of DLcdPowerHandler +*/ +void rxMsg(TAny* aPtr) + { + DLcdPowerHandler& h=*(DLcdPowerHandler*)aPtr; + TMessageBase* pM=h.iMsgQ.iMessage; + if (pM) + { + h.HandleMsg(pM); + } + } + +/** +DFC for powering up the device + +@param aPtr aPtr a pointer to an instance of DLcdPowerHandler +*/ +void power_up_dfc(TAny* aPtr) + { + ((DLcdPowerHandler*)aPtr)->PowerUpDfc(); + } + +/** +DFC for powering down the device + +@param aPtr aPtr a pointer to an instance of DLcdPowerHandler +*/ +void power_down_dfc(TAny* aPtr) + { + ((DLcdPowerHandler*)aPtr)->PowerDownDfc(); + } + + +/** +Default constructor +*/ +DLcdPowerHandler::DLcdPowerHandler() : + DPowerHandler(KLitLcd), + iPowerUpDfc(&power_up_dfc,this,6), + iPowerDownDfc(&power_down_dfc,this,7), + iBacklightOn(EFalse), + iContrast(KConfigInitialDisplayContrast), + iBrightness(KConfigInitialDisplayBrightness), + iMsgQ(rxMsg,this,NULL,1) + { + } + + +TInt DLcdPowerHandler::InitialiseController() + { + // Call Power Resource Manager to set clk value, immediately after it initialises the resource + DPowerResourceController::PostBootLevel(ENE1_TBDisplayDclkResource, EDisplayDclk24937KHz); + + //Set up layers 0-3 needed by the GCE. + //Layer 0 is associated with legacy buffer. + //Layer 1 and 2 are associated with composition buffers 0 and 1 respectively. + //Layer 3 is associated with user buffers. + + // Memory Frame control registers + AsspRegister::Write64(KHwDisplayEndianConversion, KEndianConversionValue); + + // Default to 32bpp + TUint64 PixelFormatValue = KPixelFormatValue32bpp; + if (iVideoInfo.iBitsPerPixel == 32) + { + PixelFormatValue = KPixelFormatValue32bpp; + } + else if (iVideoInfo.iBitsPerPixel == 16) + { + PixelFormatValue = KPixelFormatValue16bpp; + } + + AsspRegister::Write64(KHwDisplayPixelFormat, PixelFormatValue<<48 | PixelFormatValue<<32 | PixelFormatValue<<16 | PixelFormatValue); + + //Set up the the memory frame 0 start address to be the one of the Legacy Buffer + AsspRegister::Write64(KHwDisplayMemoryFrameAddress, ivRamPhys); + + //Memory frame 0-3 size H + TInt HValue = Lcd_Mode_Config[iInitialMode].iConfigLcdWidth-1 ; + AsspRegister::Write64(KHwDisplayMemoryFrameSizeH, (TUint64) HValue<<48 | (TUint64) HValue<<32 | HValue<<16 | HValue ) ; + + //Memory frame 0-3 size V + TInt VValue = Lcd_Mode_Config[iInitialMode].iConfigLcdHeight-1 ; + AsspRegister::Write64(KHwDisplayMemoryFrameSizeV, (TUint64) VValue<<48 | (TUint64) VValue<<32 | VValue<<16 | VValue ) ; + + //0 for all layers + AsspRegister::Write64(KHwDisplayMemoryFrameStartPointX, 0); + AsspRegister::Write64(KHwDisplayMemoryFrameStartPointY, 0); + + //Memory frame 0-3 display frame size H + HValue = Lcd_Mode_Config[iInitialMode].iConfigLcdWidth-1 ; + AsspRegister::Write64(KHwDisplayMemoryFrameDisplayFrameSizeH, (TUint64) HValue<<48 | (TUint64) HValue<<32 | HValue<<16 | HValue ); + + //Memory frame 1-3 display frame size V + VValue = Lcd_Mode_Config[iInitialMode].iConfigLcdHeight-1 ; + AsspRegister::Write64(KHwDisplayMemoryFrameDisplayFrameSizeV, (TUint64) VValue<<48 |(TUint64) VValue<<32 | VValue<<16 | VValue); + + + // Display frame control registers ( Frame 0 is associated to the Legacy buffer) + AsspRegister::Write64(KHwDisplayDisplayFrameControl, KDisplayFrameControlValue); + + //0 for all layers + AsspRegister::Write64(KHwDisplayDisplayFrameStartPointX, 1); + AsspRegister::Write64(KHwDisplayDisplayFrameStartPointY, 0); + + // Display frames 1-3 size H - Sets the horizontal size to be displayed in pixel units + TInt width = Lcd_Mode_Config[iInitialMode].iConfigLcdWidth-1; + AsspRegister::Write64(KHwDisplayDisplayFrameSizeH, (TUint64) width<<48 | (TUint64) width<<32 | width<<16 | width ); + + + // Display frames 0-3 size V - Sets the vertical size to be displayed in pixel units + TInt height = Lcd_Mode_Config[iInitialMode].iConfigLcdHeight-1; + AsspRegister::Write64(KHwDisplayDisplayFrameSizeV, (TUint64)height<<48 |(TUint64) height<<32 | height<<16 | height ); + + + // Display frames 0-3 Constant color R - G - B + AsspRegister::Write64(KHwDisplayDisplayFrameConstantColour, (TUint64) 0x404<<32 | 0x404 ); + AsspRegister::Write64(KHwDisplayDisplayFrameConstantColour + KHex8, (TUint64) 0x404<<32 | 0x404 ); + AsspRegister::Write64(KHwDisplayDisplayFrameBackgroundColour, 0x404); + + // Display control registers + AsspRegister::Write64(KHwDisplayResolutionAndCycle, RESOLUTION_AND_CYCLE); + AsspRegister::Write64(KHwDisplayPulseWidth, Lcd_Mode_Config[iInitialMode].iPulseWidth); + + AsspRegister::Write64(KHwDisplaySettings, KDisplaySettingsValue); + AsspRegister::Write64(KHwDisplayBrightness, KDisplayBrightnessVal); + + // Interface control registers + + AsspRegister::Write64(KHwDisplayInterfaceControl, KInterfaceControlValue); //sends signals out + + // Set DCLK frequency: + AsspRegister::Write32(KHwSystemCtrlBase+KHoSCUDisplayDCLKCtrl, 11); + + return KErrNone; + } + +/** +Second-phase constructor + +Called by factory function at ordinal 0 +*/ +TInt DLcdPowerHandler::Create() + { + pLcd = this; + + // map the video RAM + TInt vSize = ((NaviEngineAssp*)Arch::TheAsic())->VideoRamSize(); + ivRamPhys = TNaviEngine::VideoRamPhys(); + TInt r = DPlatChunkHw::New(iChunk,ivRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC); + if (r != KErrNone) + return r; + + //create "secure" screen immediately after normal one + iSecurevRamPhys = ivRamPhys + vSize; + TInt r2 = DPlatChunkHw::New(iSecureChunk,iSecurevRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC); + if (r2 != KErrNone) + return r2; + + TUint* pV = (TUint*)iChunk->LinearAddress(); + + __KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::Create: VideoRamSize=%x, VideoRamPhys=%08x, VideoRamLin=%08x",vSize,ivRamPhys,pV)); + + TUint* pV2 = (TUint*)iSecureChunk->LinearAddress(); + + __KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::Create: Secure display VideoRamSize=%x, VideoRamPhys=%08x, VideoRamLin=%08x",vSize,iSecurevRamPhys,pV2)); + + // Read display mode set with DIP switches 7 & 8 + // to get the requested LCD display mode + iInitialMode = ReadDipSwitchDisplayMode(); + + // setup the video info structure, this'll be used to remember the video settings + iVideoInfo.iDisplayMode = SCREEN_UNIT; + iVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[iInitialMode].iOffsetToFirstVideoBuffer; + iVideoInfo.iIsPalettized = Lcd_Mode_Config[iInitialMode].iIsPalettized; + iVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[iInitialMode].iConfigLcdWidth * (Lcd_Mode_Config[iInitialMode].iBitsPerPixel >> KShiftBitsPerByte); + iVideoInfo.iBitsPerPixel = Lcd_Mode_Config[iInitialMode].iBitsPerPixel; + iVideoInfo.iSizeInPixels.iWidth = Lcd_Mode_Config[iInitialMode].iReportedLcdWidth; + iVideoInfo.iSizeInPixels.iHeight = Lcd_Mode_Config[iInitialMode].iReportedLcdHeight; + iVideoInfo.iSizeInTwips.iWidth = PixelsToTwips(iVideoInfo.iSizeInPixels.iWidth); + iVideoInfo.iSizeInTwips.iHeight = PixelsToTwips(iVideoInfo.iSizeInPixels.iHeight); + iVideoInfo.iIsMono = KConfigLcdIsMono; + iVideoInfo.iVideoAddress = (TInt)pV; + iVideoInfo.iIsPixelOrderLandscape = KConfigLcdPixelOrderLandscape; + iVideoInfo.iIsPixelOrderRGB = KConfigLcdPixelOrderRGB; + + iSecureVideoInfo = iVideoInfo; + iSecureVideoInfo.iVideoAddress = (TInt)pV2; + + iDisplayOn = EFalse; + iSecureDisplay = EFalse; + + // install the HAL function + r=Kern::AddHalEntry(EHalGroupDisplay, halFunction, this); + if (r!=KErrNone) + return r; + + iPowerUpDfc.SetDfcQ(iDfcQ); + iPowerDownDfc.SetDfcQ(iDfcQ); + iMsgQ.SetDfcQ(iDfcQ); + iMsgQ.Receive(); + + // Alloc Physical RAM for the Composition Buffers used by the GCE + iSize = FRAME_BUFFER_SIZE(Lcd_Mode_Config[iInitialMode].iBitsPerPixel, Lcd_Mode_Config[iInitialMode].iConfigLcdWidth, Lcd_Mode_Config[iInitialMode].iConfigLcdHeight); + // double and round the page size + TUint round = Kern::RoundToPageSize(2*iSize); + + r=Epoc::AllocPhysicalRam(round , iCompositionPhysical); + if(r!=KErrNone) + { + return r; + } + + // clear interrupts + AsspRegister::Write64(KHwDisplayInterruptClear, 0x7f); + + //Set up V Sync interrupt. + //Bind Interrupt + TInt interruptId= Interrupt::Bind(EIntDisp0,Service,this); + + if (interruptId<0) + { + return interruptId; + } + + Interrupt::Enable(interruptId); + + //In case more display related interrupts are enabled KHwDisplayInterruptEnableSelection + // should be changed appropriately + + AsspRegister::Write64(KHwDisplayInterruptEnableSelection , KVSyncSelectToChannel1 ); + + // install the power handler + // power up the screen + Add(); + DisplayOn(); + + InitialiseController(); + + __KTRACE_OPT(KEXTENSION, Kern::Printf( + "Lcd_Mode_Config: mode = %d, iInitialMode %d, physical %dx%d, reporting %dx%d, bpp %d, obl %d", + iVideoInfo.iDisplayMode, iInitialMode, Lcd_Mode_Config[iInitialMode].iConfigLcdWidth, Lcd_Mode_Config[iInitialMode].iConfigLcdHeight, + iVideoInfo.iSizeInPixels.iWidth, iVideoInfo.iSizeInPixels.iHeight, iVideoInfo.iBitsPerPixel, iVideoInfo.iOffsetBetweenLines) + ); + + SplashScreen(); + + return KErrNone; + } + + + +/** + * Dispatch interrupts received by the display subsystem + * @param aPtr Argument passed to the ISR + */ +void DLcdPowerHandler::Service(TAny* aPtr) + { + DLcdPowerHandler& display = *(DLcdPowerHandler*)aPtr; + + TInt irq=__SPIN_LOCK_IRQSAVE(callbackLock); + + TUint64 dispStatus = AsspRegister::Read64(KHwDisplayInterruptStatus); + TUint64 dispEnable = AsspRegister::Read64(KHwDisplayInterruptEnable); + + TUint64 reg64 = dispEnable; + + //disable VSYNC + reg64 &= KVSyncDisable; + AsspRegister::Write64(KHwDisplayInterruptEnable , reg64 ); + + //V sync interrupt signal has been received + if( ((dispStatus & KVSyncStatus) == KVSyncStatus ) && ( ( dispEnable & KVSyncEnable ) == KVSyncEnable ) ) + { + // Call the GCE call back function in case of VSync + if ((display.iAppCallBk[0] != NULL) && (display.iAppCallBk[0]->iCbFn != NULL)) + { + (*(display.iAppCallBk[0]->iCbFn))(0,display.iAppCallBk[0]->iDataPtr); + } + if((display.iAppCallBk[1] != NULL) && (display.iAppCallBk[1]->iCbFn != NULL)) + { + (*(display.iAppCallBk[1]->iCbFn))(1,display.iAppCallBk[1]->iDataPtr); + } + } + + __SPIN_UNLOCK_IRQRESTORE(callbackLock,irq); + + reg64 = AsspRegister::Read64(KHwDisplayInterruptClear); + AsspRegister::Write64(KHwDisplayInterruptClear, reg64 | KVSyncClear); //CLear Vsync interrupt bit + + } + + +/** + * Register the call back function. + * Components interested in receiving notification of the Vsync interrupt should register a callback function. + */ +EXPORT_C TInt DLcdPowerHandler::RegisterCallback(TLcdUserCallBack* aCbPtr) +{ + __KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::RegisterCallBack %08x\n",aCbPtr->iCbFn) ); + + TInt irq=__SPIN_LOCK_IRQSAVE(callbackLock); + + if(aCbPtr != NULL) + { + if ( pLcd->iAppCallBk[0] == NULL ) + { + pLcd->iAppCallBk[0] = aCbPtr; + } + else + { + if((pLcd->iAppCallBk[1] == NULL) && (pLcd->iAppCallBk[0]->iCbFn != aCbPtr->iCbFn)) + { + pLcd->iAppCallBk[1] = aCbPtr; + } + else + { + __SPIN_UNLOCK_IRQRESTORE(callbackLock,irq); + return KErrInUse; + } + } + + __SPIN_UNLOCK_IRQRESTORE(callbackLock,irq); + return KErrNone; + } + else + { + __SPIN_UNLOCK_IRQRESTORE(callbackLock,irq); + __KTRACE_OPT(KEXTENSION, Kern::Printf("Error: The supplied listener's callback is NULL")); + return KErrArgument; + } +} + + +/** + *DeRegister the call back function + */ +EXPORT_C void DLcdPowerHandler::DeRegisterCallback(TLcdUserCallBack* aCbPtr) +{ + __KTRACE_OPT(KEXTENSION ,Kern::Printf("DLcdPowerHandler::DeRegisterCallBack %08x\n ",aCbPtr->iCbFn) ); + + TInt irq=__SPIN_LOCK_IRQSAVE(callbackLock); + if(aCbPtr != NULL) + { + if( pLcd->iAppCallBk[0] != NULL) + { + if ( (pLcd->iAppCallBk[0]->iDataPtr == aCbPtr->iDataPtr) && (pLcd->iAppCallBk[0]->iCbFn == aCbPtr->iCbFn) ) + { + pLcd->iAppCallBk[0] = NULL; + } + } + + if( pLcd->iAppCallBk[1] != NULL) + { + if ( (pLcd->iAppCallBk[1]->iDataPtr == aCbPtr->iDataPtr) && (pLcd->iAppCallBk[1]->iCbFn == aCbPtr->iCbFn) ) + { + pLcd->iAppCallBk[1] = NULL; + } + } + } + __SPIN_UNLOCK_IRQRESTORE(callbackLock,irq); +} + + +/** +Turn the display on +May be called as a result of a power transition or from the HAL +If called from HAL, then the display may be already be on (iDisplayOn == ETrue) +*/ +void DLcdPowerHandler::DisplayOn() + { + __KTRACE_OPT(KPOWER, Kern::Printf("DisplayOn %d", iDisplayOn)); + if (!iDisplayOn) // may have been powered up already + { + iDisplayOn = ETrue; + PowerUpLcd(iSecureDisplay); + SetContrast(iContrast); + SetBrightness(iBrightness); + } + } + +/** +Turn the display off +May be called as a result of a power transition or from the HAL +If called from Power Manager, then the display may be already be off (iDisplayOn == EFalse) +if the platform is in silent running mode +*/ +void DLcdPowerHandler::DisplayOff() + { + __KTRACE_OPT(KPOWER, Kern::Printf("DisplayOff %d", iDisplayOn)); + if (iDisplayOn) + { + iDisplayOn = EFalse; + PowerDownLcd(); + } + } + +/** +Switch between secure and non-secure displays + +@param aSecure ETrue if switching to secure display +*/ +void DLcdPowerHandler::SwitchDisplay(TBool aSecure) + { + if (aSecure) + { + if (!iSecureDisplay) + { + TThreadMessage& m=Kern::Message(); + m.iValue = EDisplayHalSetSecure; + m.SendReceive(&iMsgQ); // send a message and block Client thread until secure display has been enabled. + } + } + else + { + if (iSecureDisplay) + { + TThreadMessage& m=Kern::Message(); + m.iValue = -EDisplayHalSetSecure; + m.SendReceive(&iMsgQ); // send a message and block Client thread until secure display has been disabled. + } + } + } + + +/** +Switch to secure display + +*/ +void DLcdPowerHandler::SwitchToSecureDisplay() + { + DisplayOff(); + iSecureDisplay = ETrue; + DisplayOn(); + } + + +/** +Switch from secure display + +*/ +void DLcdPowerHandler::SwitchFromSecureDisplay() + { + DisplayOff(); + iSecureDisplay = EFalse; + DisplayOn(); + } + + +/** +DFC to power up the display +*/ +void DLcdPowerHandler::PowerUpDfc() + { + __KTRACE_OPT(KPOWER, Kern::Printf("PowerUpDfc")); + DisplayOn(); + + PowerUpDone(); // must be called from a different thread than PowerUp() + } + +/** +DFC to power down the display +*/ +void DLcdPowerHandler::PowerDownDfc() + { + __KTRACE_OPT(KPOWER, Kern::Printf("PowerDownDfc")); + DisplayOff(); + PowerDownDone(); // must be called from a different thread than PowerUp() + } + +/** +Schedule the power-down DFC +*/ +void DLcdPowerHandler::PowerDown(TPowerState) + { + iPowerDownDfc.Enque(); // schedules DFC to execute on this driver's thread + } + +/** +Schedule the power-up DFC +*/ +void DLcdPowerHandler::PowerUp() + { + iPowerUpDfc.Enque(); // schedules DFC to execute on this driver's thread + } + +/** +Power up the display + +@param aSecure ETrue if powering up the secure display +*/ +void DLcdPowerHandler::PowerUpLcd(TBool aSecure) + { + AsspRegister::Write16(KHwLCDDispBase,0x140); //power-up board and backlight + } + +/** +Power down the display and the backlight +*/ +void DLcdPowerHandler::PowerDownLcd() + { + SetBacklightState(EFalse); + AsspRegister::Write16(KHwLCDDispBase, 0x143); //power-down board and backlight + } + +/** +Set the Lcd contrast + +@param aValue the contrast setting +*/ +TInt DLcdPowerHandler::SetContrast(TInt aValue) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("SetContrast(%d)", aValue)); + + if (aValue >= KConfigLcdMinDisplayContrast && aValue <= KConfigLcdMaxDisplayContrast) + { + iContrast=aValue; + return KErrNone; + } + + return KErrArgument; + } + +/** +Queue a message to set the Lcd Contrast + +@param aValue the contrast setting +*/ +TInt DLcdPowerHandler::HalSetContrast(TInt aValue) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("HalSetContrast(%d)", aValue)); + + TThreadMessage& m=Kern::Message(); + m.iValue = EDisplayHalSetDisplayContrast; + m.iArg[0] = (TAny *) aValue; + + return ( m.SendReceive(&iMsgQ) ); // send a message and block Client thread until contrast has been set. + } + + + +/** +Set the Lcd brightness + +@param aValue the brightness setting +*/ +TInt DLcdPowerHandler::SetBrightness(TInt aValue) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("SetBrightness(%d)", aValue)); + + if (aValue >= KConfigLcdMinDisplayBrightness && aValue <= KConfigLcdMaxDisplayBrightness) + { + iBrightness=aValue; + + return KErrNone; + } + return KErrArgument; + } + +/** +Queue a message to set the Lcd brightness + +@param aValue the brightness setting +*/ +TInt DLcdPowerHandler::HalSetBrightness(TInt aValue) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("HalSetBrightness(%d)", aValue)); + + TThreadMessage& m=Kern::Message(); + m.iValue = EDisplayHalSetDisplayBrightness; + m.iArg[0]= (TAny *) aValue; + + return (m.SendReceive(&iMsgQ)); // send a message and block Client thread until brightness has been set. + } + + +/** +Turn the backlight on +*/ +void DLcdPowerHandler::BacklightOn() + { + // turn the backlight on + AsspRegister::Write16(KHwLCDDispBase, 0x140); + } + +/** +Turn the backlight off +*/ +void DLcdPowerHandler::BacklightOff() + { + // turn the backlight off + AsspRegister::Write16(KHwLCDDispBase, 0x142); + } + +/** +Set the state of the backlight + +@param aState ETrue if setting the backlight on +*/ +void DLcdPowerHandler::SetBacklightState(TBool aState) + { + iBacklightOn=aState; + if (iBacklightOn) + BacklightOn(); + else + BacklightOff(); + } + +void DLcdPowerHandler::ScreenInfo(TScreenInfoV01& anInfo) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("DLcdPowerHandler::ScreenInfo")); + + anInfo.iWindowHandleValid = EFalse; + anInfo.iWindowHandle = NULL; + anInfo.iScreenAddressValid = ETrue; + anInfo.iScreenAddress = (TAny *)(iChunk->LinearAddress()); + anInfo.iScreenSize.iWidth = Lcd_Mode_Config[iInitialMode].iReportedLcdWidth; + anInfo.iScreenSize.iHeight = Lcd_Mode_Config[iInitialMode].iReportedLcdHeight; + } + +/** +Handle a message from the power handler +*/ +void DLcdPowerHandler::HandleMsg(TMessageBase* aMsg) +{ + TInt r = KErrNone; + TThreadMessage& m=*(TThreadMessage*)aMsg; + switch(m.iValue) + { + case EDisplayHalWsSwitchOnScreen: + DisplayOn(); + break; + case (-EDisplayHalWsSwitchOnScreen): + DisplayOff(); + break; + case EDisplayHalSetSecure: + SwitchToSecureDisplay(); + break; + case (-EDisplayHalSetSecure): + SwitchFromSecureDisplay(); + break; + case EDisplayHalSetDisplayContrast: + { + r = SetContrast(m.Int0()); + break; + } + case EDisplayHalSetDisplayBrightness: + { + r = SetBrightness(m.Int0()); + break; + default: + r = KErrNotSupported; + __KTRACE_OPT(KHARDWARE,Kern::Printf("DLcdPowerHandler::HalFunction %d defaulted", m.iValue)); + break; + } + } + + m.Complete(r, ETrue); + } + +/** +Send a message to the power-handler message queue to turn the display on +*/ +void DLcdPowerHandler::WsSwitchOnScreen() + { + TThreadMessage& m=Kern::Message(); + m.iValue = EDisplayHalWsSwitchOnScreen; + m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered up + } + +/** +Send a message to the power-handler message queue to turn the display off +*/ +void DLcdPowerHandler::WsSwitchOffScreen() + { + TThreadMessage& m=Kern::Message(); + m.iValue = -EDisplayHalWsSwitchOnScreen; + m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered down + } + +/** +Return information about the current display mode + +@param aInfo a structure supplied by the caller to be filled by this function. +@param aSecure ETrue if requesting information about the secure display +@return KErrNone if successful +*/ +TInt DLcdPowerHandler::GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("GetCurrentDisplayModeInfo")); + NKern::FMWait(&iLock); + if (aSecure) + aInfo = iSecureVideoInfo; + else + aInfo = iVideoInfo; + NKern::FMSignal(&iLock); + return KErrNone; + } + +/** +Return information about the specified display mode + +@param aScreenNumber the screen number to query +@param aInfo a structure supplied by the caller to be filled by this function. +@return KErrNone if successful +*/ +TInt DLcdPowerHandler::GetSpecifiedDisplayModeInfo(TInt aScreenNumber, TVideoInfoV01& aInfo) + { + __KTRACE_OPT(KEXTENSION, Kern::Printf("GetSpecifiedDisplayModeInfo screen unit is %d",aScreenNumber)); + + if (aScreenNumber < 0 || aScreenNumber >= SCREEN_UNIT_COUNT) + return KErrArgument; + + NKern::FMWait(&iLock); + aInfo = iVideoInfo; + NKern::FMSignal(&iLock); + + return KErrNone; + } + +/** +Set the display mode + +@param aScreenNumber the screen number to set +*/ +TInt DLcdPowerHandler::SetDisplayMode(TInt aScreenNumber) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("SetDisplayMode ( screen unit) = %d", aScreenNumber)); + + if (aScreenNumber < 0 || aScreenNumber >= SCREEN_UNIT_COUNT) + return KErrArgument; + + NKern::FMWait(&iLock); + + // store the current mode + iVideoInfo.iDisplayMode = SCREEN_UNIT; + iVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[iInitialMode].iOffsetToFirstVideoBuffer; + iVideoInfo.iIsPalettized = Lcd_Mode_Config[iInitialMode].iIsPalettized; + iVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[iInitialMode].iConfigLcdWidth * (Lcd_Mode_Config[iInitialMode].iBitsPerPixel >> KShiftBitsPerByte); + iVideoInfo.iBitsPerPixel = Lcd_Mode_Config[iInitialMode].iBitsPerPixel; + + // store the current mode for secure screen + iSecureVideoInfo.iDisplayMode = SCREEN_UNIT; + iSecureVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[iInitialMode].iOffsetToFirstVideoBuffer; + iSecureVideoInfo.iIsPalettized = Lcd_Mode_Config[iInitialMode].iIsPalettized; + iSecureVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[iInitialMode].iConfigLcdWidth * (Lcd_Mode_Config[iInitialMode].iBitsPerPixel >> KShiftBitsPerByte); + iSecureVideoInfo.iBitsPerPixel = Lcd_Mode_Config[iInitialMode].iBitsPerPixel; + + NKern::FMSignal(&iLock); + + __KTRACE_OPT(KEXTENSION,Kern::Printf("SetDisplayMode screenNumber = %d, otfp = %d, palettized = %d, bpp = %d, obl = %d", + aScreenNumber, iVideoInfo.iOffsetToFirstPixel, iVideoInfo.iIsPalettized, iVideoInfo.iBitsPerPixel, iVideoInfo.iOffsetBetweenLines)); + + return KErrNone; + } + +/** +Fill the video memory with an initial pattern or image +This will be displayed on boot-up +*/ +const TInt KGranularity = 4; + +void DLcdPowerHandler::SplashScreen() + { + //initialise the video ram to be a splash screen + + __KTRACE_OPT(KEXTENSION,Kern::Printf("SplashScreen")); + + TInt xres, yres, bpp, bpl, ofp; + TLinAddr addr; + addr = (TLinAddr)iVideoInfo.iVideoAddress; + xres = iVideoInfo.iSizeInPixels.iWidth; + yres = iVideoInfo.iSizeInPixels.iHeight; + bpp = iVideoInfo.iBitsPerPixel; + bpl = iVideoInfo.iOffsetBetweenLines; + ofp = iVideoInfo.iOffsetToFirstPixel; + + TInt xb, yb; + + for (yb=0; yb>1)%251; + c^=0xff; + TUint r=c&7; + TUint g=(c>>3)&7; + TUint b=(c>>6); + TUint c16=(b<<14)|(g<<8)|(r<<2); + c16 |= (c16<<16); + TUint c8=c|(c<<8); + c8 |= (c8<<16); + TUint c32=(b<<22)|(g<<13)|(r<<5); + TInt baddr=addr+ofp+yb*KGranularity*bpl+xb*KGranularity*bpp/8; + TInt l; + for (l=0; l8) + pixelSize = (pixelSize+7)&~7; // Round up to whole number of bytes + TInt bytesPerLine = (pixelSize*iSecureVideoInfo.iSizeInPixels.iWidth) >> 3; + for(TInt y=0; y= NumberOfPaletteEntries())) + { + NKern::FMSignal(&iLock); + return KErrArgument; + } + + NKern::FMSignal(&iLock); + + __KTRACE_OPT(KEXTENSION,Kern::Printf("GetPaletteEntry %d color 0x%x", aEntry, aColor)); + + return KErrNone; + } + +/** +Set the palette entry at a particular offset + +@param aEntry the palette index +@param aColor the RGB color to store +@return KErrNone if successful + KErrNotSupported if the current vide mode does not support a palette + KErrArgument if aEntry is out of range +*/ +TInt DLcdPowerHandler::SetPaletteEntry(TInt aEntry, TInt aColor) + { + + NKern::FMWait(&iLock); + if (!iVideoInfo.iIsPalettized) + { + NKern::FMSignal(&iLock); + return KErrNotSupported; + } + + if ((aEntry < 0) || (aEntry >= NumberOfPaletteEntries())) //check entry in range + { + NKern::FMSignal(&iLock); + return KErrArgument; + } + + NKern::FMSignal(&iLock); + __KTRACE_OPT(KEXTENSION,Kern::Printf("SetPaletteEntry %d to 0x%x", aEntry, aColor )); + + return KErrNone; + } + +/** +a HAL entry handling function for HAL group attribute EHalGroupDisplay. +The HalFunction is called in the context of the user thread which is +requesting the particular HAL display function. + +@param a1 an arbitrary argument +@param a2 an arbitrary argument +@return KErrNone if successful +*/ +TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2) + { + TInt r=KErrNone; + switch(aFunction) + { + case EDisplayHalScreenInfo: + { + TPckgBuf vPckg; + ScreenInfo(vPckg()); + Kern::InfoCopy(*(TDes8*)a1,vPckg); + break; + } + + case EDisplayHalWsRegisterSwitchOnScreenHandling: + iWsSwitchOnScreen=(TBool)a1; + break; + + case EDisplayHalWsSwitchOnScreen: + WsSwitchOnScreen(); + break; + + case EDisplayHalMaxDisplayContrast: + { + TInt mc=KConfigLcdMaxDisplayContrast; + kumemput32(a1,&mc,sizeof(mc)); + break; + } + case EDisplayHalSetDisplayContrast: + if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayContrast"))) + return KErrPermissionDenied; + r=HalSetContrast(TInt(a1)); + break; + + case EDisplayHalDisplayContrast: + kumemput32(a1,&iContrast,sizeof(iContrast)); + break; + + case EDisplayHalMaxDisplayBrightness: + { + TInt mc=KConfigLcdMaxDisplayBrightness; + kumemput32(a1,&mc,sizeof(mc)); + break; + } + + case EDisplayHalSetDisplayBrightness: + if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayBrightness"))) + return KErrPermissionDenied; + r=HalSetBrightness(TInt(a1)); + break; + + case EDisplayHalDisplayBrightness: + kumemput32(a1,&iBrightness,sizeof(iBrightness)); + break; + + case EDisplayHalSetBacklightOn: + if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetBacklightOn"))) + return KErrPermissionDenied; + if (Kern::MachinePowerStatus() vPckg; + r = GetCurrentDisplayModeInfo(vPckg(), (TBool)a2); + if (KErrNone == r) + Kern::InfoCopy(*(TDes8*)a1,vPckg); + } + break; + + case EDisplayHalSpecifiedModeInfo: + { + TPckgBuf vPckg; + TInt screenNumber; + kumemget32(&screenNumber, a1, sizeof(screenNumber)); + r = GetSpecifiedDisplayModeInfo(screenNumber, vPckg()); + if (KErrNone == r) + Kern::InfoCopy(*(TDes8*)a2,vPckg); + } + break; + + case EDisplayHalSecure: + kumemput32(a1, &iSecureDisplay, sizeof(TBool)); + break; + + case EDisplayHalSetSecure: + { + if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetSecure"))) + return KErrPermissionDenied; + SwitchDisplay((TBool)a1); + } + break; + + default: + r=KErrNotSupported; + break; + } + return r; + } + + +DECLARE_STANDARD_EXTENSION() + { + __KTRACE_OPT(KPOWER,Kern::Printf("Starting LCD power manager")); + + // create LCD power handler + TInt r=KErrNoMemory; + DLcdPowerHandler* pH=new DLcdPowerHandler; + if (pH) + { + //The same DFC queue will be used by both the LCD extension and GCE PDD + r= Kern::DfcQCreate( pH->iDfcQ, KDisplay0ThreadPriority, &KDisplay0DfcThread ); + if ( r == KErrNone) + { + r =pH->Create(); + __KTRACE_OPT(KPOWER,Kern::Printf("Returns %d",r)); + + if ( r == KErrNone) + { + DDisplayPddFactory * device = new DDisplayPddFactory; + + if (device==NULL) + { + r=KErrNoMemory; + } + else + { + r=Kern::InstallPhysicalDevice(device); + } + + #ifdef CPU_AFFINITY_ANY + NKern::ThreadSetCpuAffinity((NThread*) pH->iDfcQ->iThread, KCpuAffinityAny); + #endif + + __KTRACE_OPT(KEXTENSION,Kern::Printf("Installing the display device from the kernel extension returned with error code %d",r)); + + } + } + + } + return r; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/lcdgce/lcdgce.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/lcdgce/lcdgce.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,297 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\lcdgce\lcdgce.h +* +*/ + + + +/** + @file Definitions for the ne1_tb GCE PDD + @internalTechnology + @prototype +*/ + +#ifndef __LCDGCE_H__ +#define __LCDGCE_H__ + +#include + + +const TUint KVSyncEnable = 1<<1; +const TUint64 KVSyncDisable = ~(TUint64)(KVSyncEnable) ; +const TUint KVSyncClear = 1<<1; +const TUint KVSyncStatus = 1<<1; +const TUint KVSyncSelectToChannel1 = 1<<8; + +const TUint KHex8 = 0x8; + + +/* The available display modes. + These modes can be changed by software, but the initial mode is specified by + DSW1 DIP switch settings (7 & 8) as described in the table below: + +DSW1 | 7 8 | +----------------------------------------------------------------------------------------------------- + | 0 0 | 640 x 480 | D-SUB | landscape | VGA on analog 15 pin DSUB connector + | 0 1 | 800 x 480 | NEC LCD | landscape | WVGA + | 1 0 | 480 x 640 | Hitachi LCD | portrait | VGA (LCD switches: SW4=0111, SW5=0, SW6=0, SW7=0) + | 1 1 | 320 x 240 | D-SUB | landscape | QVGA on analog 15 pin DSUB connector +*/ +enum TVideoMode + { + DISPLAY_MODE_ANALOG_VGA = 0, + DISPLAY_MODE_HITACHI_VGA, + DISPLAY_MODE_ANALOG_QVGA_LANDSCAPE_OLD, + DISPLAY_MODE_HITACHI_QVGA, + DISPLAY_MODE_NEC_WVGA, + DISPLAY_MODE_ANALOG_QVGA_PORTRAIT, + DISPLAY_MODE_ANALOG_QVGA_LANDSCAPE, + + DISPLAY_NUM_MODES + }; + +inline TInt ReadDipSwitchDisplayMode() + { + // Check the IDMODE register for DIP switch settings + // to set the requested display mode + // Read bits 12 and 13 from IDMODE register to get the LCD mode + TUint switches = (AsspRegister::Read32(KHwIDMODE) & KHmLcdSwitches) >> KHsLcdSwitches; + + TInt mode = 0; + switch (switches) + { + default: + case 0: + mode = DISPLAY_MODE_ANALOG_VGA; + break; + case 1: + mode = DISPLAY_MODE_HITACHI_VGA; + break; + case 2: + mode = DISPLAY_MODE_NEC_WVGA; + break; + case 3: + mode = DISPLAY_MODE_ANALOG_QVGA_LANDSCAPE; + break; + // An alternative case 3 line for QVGA Portrait + // case 3: iInitialMode = DISPLAY_MODE_ANALOG_QVGA_PORTRAIT; break; + } + return mode; + } + +/********************************************************************/ +/* Class Definition */ +/********************************************************************/ +/** + * This class defines a callback mechanism that is used by a resource user to specify its callback. It contains a + * function pointer and data pointer. The function pointer specifies the user callback function to be invoked by the + * resource while the data pointer specifies the data to be passed to the callback function. + */ +class TLcdUserCallBack + { +public: + // The constructor for the callback mechanism. + TLcdUserCallBack(TInt (*aFunction)(TUint aResID, TAny* aPtr), TAny* aPtr) + + { + iCbFn = aFunction; + iDataPtr = aPtr; + } + +public: + // The callback function pointer. + TInt (*iCbFn)(TUint aResID, TAny* aPtr); + + // Pointer to the data structure to be passed to the callback function. + TAny *iDataPtr; + }; + + +/** + PDD Factory class + */ + +class DDisplayPddFactory : public DPhysicalDevice + { +public: + DDisplayPddFactory(); + + virtual TInt Install(); + virtual void GetCaps(TDes8& aDes) const; + virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); + virtual TInt Validate(TInt aDeviceType, const TDesC8* anInfo, const TVersion& aVer); + }; + + + +class DDisplayPddNaviEng : public DDisplayPdd + { + + public: + DDisplayPddNaviEng(); + ~DDisplayPddNaviEng(); + + + //Inherited from DDisplayPdd + TInt SetLegacyMode(); + TInt SetGceMode(); + TInt SetRotation(RDisplayChannel::TDisplayRotation aRotation); + + TInt PostUserBuffer(TBufferNode* aNode); + TInt PostCompositionBuffer(TBufferNode* aNode); + TInt PostLegacyBuffer(); + + TBool PostPending(); + + TInt CloseMsg(); + TInt CreateChannelSetup(TInt aUnit); + TDfcQue* DfcQ(TInt aUnit); + +public: + void VSyncIsr(); + static void VSyncDfcFn(TAny* aChannel); + + + +private: + TDfcQue* iDfcQ; + + //generic display info + TVideoInfoV01 iScreenInfo; + + //Pointer to a buffer in the Pending state + TBufferNode* iPendingBuffer; + + //Pointer to a buffer in the Active state + TBufferNode* iActiveBuffer; + + DChunk * iChunk; + TLcdUserCallBack* iLcdCallback; + + public: + TDfc iVSyncDfc; + + }; + + +// +// Add any private functions and data you require +// +NONSHARABLE_CLASS(DLcdPowerHandler) : public DPowerHandler + { +public: + DLcdPowerHandler(); + + // from DPowerHandler + void PowerDown(TPowerState); + void PowerUp(); + + void PowerUpDfc(); + void PowerDownDfc(); + + TInt Create(); + void DisplayOn(); + void DisplayOff(); + TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2); + + void PowerUpLcd(TBool aSecure); + void PowerDownLcd(); + + void ScreenInfo(TScreenInfoV01& aInfo); + void WsSwitchOnScreen(); + void WsSwitchOffScreen(); + void HandleMsg(TMessageBase* aMsg); + void SwitchDisplay(TBool aSecure); + + void SetBacklightState(TBool aState); + void BacklightOn(); + void BacklightOff(); + TInt SetContrast(TInt aContrast); + TInt HalSetContrast(TInt aContrast); + TInt SetBrightness(TInt aBrightness); + TInt HalSetBrightness(TInt aBrightness); + void SwitchToSecureDisplay(); + void SwitchFromSecureDisplay(); + +private: + TInt SetPaletteEntry(TInt aEntry, TInt aColor); + TInt GetPaletteEntry(TInt aEntry, TInt* aColor); + TInt NumberOfPaletteEntries(); + TInt GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure); + TInt GetSpecifiedDisplayModeInfo(TInt aMode, TVideoInfoV01& aInfo); + TInt SetDisplayMode(TInt aMode); + void SplashScreen(); + TInt GetDisplayColors(TInt* aColors); + +public: + TInt InitialiseController(); + static void Service(TAny* aPtr); + + IMPORT_C static TInt RegisterCallback(TLcdUserCallBack* aCbPtr); + IMPORT_C static void DeRegisterCallback(TLcdUserCallBack* aCbPtr); + +private: + TBool iIsPalettized; + TBool iDisplayOn; // to prevent a race condition with WServer trying to power up/down at the same time + DPlatChunkHw* iChunk; + DPlatChunkHw* iSecureChunk; + TBool iWsSwitchOnScreen; + TBool iSecureDisplay; + + TDfc iPowerUpDfc; + TDfc iPowerDownDfc; + + TVideoInfoV01 iSecureVideoInfo; + NFastMutex iLock; // protects against being preempted whilst manipulating iVideoInfo/iSecureVideoInfo + TPhysAddr ivRamPhys; + TPhysAddr iSecurevRamPhys; + + TBool iBacklightOn; + TInt iContrast; + TInt iBrightness; + TUint iInitialMode; + + + TLcdUserCallBack * iAppCallBk[2]; + +public: + TMessageQue iMsgQ; + TDfcQue* iDfcQ; + TVideoInfoV01 iVideoInfo; + TInt iSize; + TPhysAddr iCompositionPhysical; + + static DLcdPowerHandler * pLcd; + + }; + + +//#define _GCE_NAVIDISPLAY_DEBUG + +#ifdef _GCE_NAVIDISPLAY_DEBUG + +#define __GCE_DEBUG_PRINT(a) Kern::Printf(a) +#define __GCE_DEBUG_PRINT2(a,b) Kern::Printf(a,b) + +#else + +#define __GCE_DEBUG_PRINT(a) +#define __GCE_DEBUG_PRINT2(a,b) + +#endif + + +#endif //__LCDGCE_H__ diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/navi_i2s.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/navi_i2s.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* bsp\hwip_nec_navienegine\navienegine_assp\i2s.h +* +*/ + + + +#include +#include +#include +#include + + +// +// each channel should implemment the platform specific interface + +class DI2sChannelBase + { +public: + static TInt CreateChannels(DI2sChannelBase*& aChannel, TInt aInterfaceId); + + virtual TInt ConfigureInterface(TDes8* aConfig) = 0; + virtual TInt GetInterfaceConfiguration(TDes8& aConfig) = 0; + virtual TInt SetSamplingRate(TInt aSamplingRate) = 0; + virtual TInt GetSamplingRate(TInt& aSamplingRate) = 0; + virtual TInt SetFrameLengthAndFormat(TInt aFrameLength, TInt aLeftFramePhaseLength) = 0; + virtual TInt GetFrameFormat(TInt& aLeftFramePhaseLength, TInt& aRightFramePhaseLength) = 0; + virtual TInt SetSampleLength(TInt aFramePhase, TInt aSampleLength) = 0; + virtual TInt GetSampleLength(TInt aFramePhase, TInt& aSampleLength) = 0; + virtual TInt SetDelayCycles(TInt aFramePhase, TInt aDelayCycles) = 0; + virtual TInt GetDelayCycles(TInt aFramePhase, TInt& aDelayCycles) = 0; + virtual TInt ReadReceiveRegister(TInt aFramePhase, TInt& aData) = 0; + virtual TInt WriteTransmitRegister(TInt aFramePhase, TInt aData) = 0; + virtual TInt ReadTransmitRegister(TInt aFramePhase, TInt& aData) = 0; + virtual TInt ReadRegisterModeStatus(TInt aFramePhase, TInt& aFlags) = 0; + virtual TInt EnableRegisterInterrupts(TInt aFramePhase, TInt aInterrupt) = 0; + virtual TInt DisableRegisterInterrupts(TInt aFramePhase, TInt aInterrupt) = 0; + virtual TInt IsRegisterInterruptEnabled(TInt aFramePhase, TInt& aEnabled) = 0; + virtual TInt EnableFIFO(TInt aFramePhase, TInt aFifoMask) = 0; + virtual TInt DisableFIFO(TInt aFramePhase, TInt aFifoMask) = 0; + virtual TInt IsFIFOEnabled(TInt aFramePhase, TInt& aEnabled) = 0; + virtual TInt SetFIFOThreshold(TInt aFramePhase, TInt aDirection, TInt aThreshold) = 0; + virtual TInt ReadFIFOModeStatus(TInt aFramePhase, TInt& aFlags) = 0; + virtual TInt EnableFIFOInterrupts(TInt aFramePhase, TInt aInterrupt) = 0; + virtual TInt DisableFIFOInterrupts(TInt aFramePhase, TInt aInterrupt) = 0; + virtual TInt IsFIFOInterruptEnabled(TInt aFramePhase, TInt& aEnabled) = 0; + virtual TInt ReadFIFOLevel(TInt aFramePhase, TInt aDirection, TInt& aLevel) = 0; + virtual TInt EnableDMA(TInt aFifoMask) = 0; + virtual TInt DisableDMA(TInt aFifoMask) = 0; + virtual TInt IsDMAEnabled(TInt& aEnabled) = 0; + virtual TInt Start(TInt aDirection) = 0; + virtual TInt Stop(TInt aDirection) = 0; + virtual TInt IsStarted(TInt aDirection, TBool& aStarted) = 0; + +protected: + TInt iInterfaceId; + TI2sConfigV01 iConfig; + }; + +/** +The management class for all I2S channels +*/ +class TI2sManager + { +public: + // initialisation + TInt DoCreate(); +public: + static DI2sChannelBase **iChannels; // array of pointers to channels (populated in DoCreate); indexed by the channel number portion of interface ID (bottom 16 bits) + static TInt iChannelsNum; // to store number of channels present on the system (obtained from ConfRep and set in DoCreate) + }; + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/naviengine.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/naviengine.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,520 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\naviengine.h +* Definitions for NE1_TBVariant ASSP +* +*/ + + + +#ifndef __A32NAVIENGINE_H__ +#define __A32NAVIENGINE_H__ +#include +#include + +//------------------------------------------------------------------- +// Constant conventions: +//------------------------------------------------------------------- + +// KH Hardware definition +// KHw 4-byte word definition prefix +// KHb Byte definition prefix +// KHt Bit definition prefix +// KHm Mask definition prefix +// KHs Shift definition prefix +// KHo Offset definition prefix +// KHwRo Read-only register +// KHwWo Write-only register +// KHwRw Read/write register +// KHwBase Base address within memory map +// _i Input suffix +// _o Output suffix +// _b Input/output suffix +// +// ALL ASSP specific hardware registers should be defined in this file, not +// in local files. The register belongs to the ASSP, not the driver. + +//---------------------------------------------------------------------------- +// Memory map: physical addresses +//---------------------------------------------------------------------------- + +// These details are taken directly from the NaviEngine SoC TRM "S18599EJ1V0UM00.pdf" +// Table 4-1 Address Map +const TUint KHwBaseMPcorePrivatePhys = 0xc0000000; // Private MPcore region for SCU and Interrupt controller (8k address space) +const TUint KHwDDR2RamBasePhys = 0x80000000; // 256MB of DDR2 RAM sits here (in a 1GB address space) +const TUint KHwPCIPhys = 0x20000000; // PCI controller (128MB address space) +const TUint KHwInternal = 0x18000000; // Internal SoC peripherals reside in this area (16MB address space) + +// Table 4-2 AXI Address Map +const TUint KHwAXI64IC2Phys = 0x80000000; // AXI64 bus base address +const TUint KHwSATAPhys = 0x18016000; // SATA Controller +const TUint KHwAXI64DMACPhys = 0x18015000; // DMA Controller for the AXI64 bus +const TUint KHwVideoPhys = 0x18014000; // External Video Controller +const TUint KHwDispPhys = 0x18010000; // LCD/VGA display controller +const TUint KHwSGXPhys = 0x18000000; // SGX display controller + +// Table 4-3 AHB Address Map +const TUint KHwCFWindow2Phys = 0x18070000; +const TUint KHwCFWindow1Phys = 0x18060000; +const TUint KHwCFWindow0Phys = 0x18050000; +const TUint KHwATA6_CS1Phys = 0x18029000; +const TUint KHwATA6_CS0Phys = 0x18028000; +const TUint KHwUSBHPhys = 0x18024000; // Internal PCI controller memory window +const TUint KHwAHB32PCI_USBPhys = 0x18023000; // PCI controller for the internal USB controller +const TUint KHwAHB32PCI_ExtPhys = 0x18022000; // PCI controller for the external PCI bus +const TUint KHwDDR2RegPhys = 0x18021000; // DDR2 memory control registers +const TUint KHwAHB0DMAC4Phys = 0x18020000; // AHB bus DMA Controller 4 +const TUint KHwAHB0DMAC3Phys = 0x1801f000; // AHB bus DMA Controller 3 +const TUint KHwAHB0DMAC2Phys = 0x1801e000; // AHB bus DMA Controller 2 +const TUint KHwAHB0DMAC1Phys = 0x1801d000; // AHB bus DMA Controller 1 +const TUint KHwAHB0DMAC0Phys = 0x1801c000; // AHB bus DMA Controller 0 +const TUint KHwAHBEXDMACPhys = 0x1801b000; // AHB bus DMA Controller on external bus +const TUint KHwEXBUSPhys = 0x18018000; // External Bus / NAND / CF + +// Table 4-4 APB Address Map +const TUint KHwDTVIfPhys = 0x1804C000; // Digital TV interface +const TUint KHwAPB1Phys = 0x18030000; // AHB32APB bus base address + +const TUint KHwPWM7Phys = 0x1803AC00; +const TUint KHwPWM6Phys = 0x1803A800; +const TUint KHwPWM5Phys = 0x1803A400; +const TUint KHwPWM4Phys = 0x1803A000; +const TUint KHwPWM3Phys = 0x18039C00; +const TUint KHwPWM2Phys = 0x18039800; +const TUint KHwPWM1Phys = 0x18039400; +const TUint KHwPWM0Phys = 0x18039000; +const TUint KHwGPIOPhys = 0x18038000; // GPIO module +const TUint KHwSYSCTRLPhys = 0x18037C00; // System Control Unit +const TUint KHweWDTPhys = 0x18037800; // External Watchdog Timer +const TUint KHwTimer5Phys = 0x18037400; // Timers +const TUint KHwTimer4Phys = 0x18037000; +const TUint KHwTimer3Phys = 0x18036C00; +const TUint KHwTimer2Phys = 0x18036800; +const TUint KHwTimer1Phys = 0x18036400; +const TUint KHwTimer0Phys = 0x18036000; +const TUint KHwUART7Phys = 0x18035C00; // UARTs +const TUint KHwUART6Phys = 0x18035800; +const TUint KHwUART5Phys = 0x18035400; +const TUint KHwUART4Phys = 0x18035000; +const TUint KHwUART3Phys = 0x18034C00; +const TUint KHwUART2Phys = 0x18034800; +const TUint KHwUART1Phys = 0x18034400; +const TUint KHwUART0Phys = 0x18034000; +const TUint KHwI2S3Phys = 0x18033000; // I2S +const TUint KHwI2S2Phys = 0x18032C00; +const TUint KHwI2S1Phys = 0x18032800; +const TUint KHwI2S0Phys = 0x18032400; +const TUint KHwI2CPhys = 0x18032000; // I2C +const TUint KHwCSI1Phys = 0x18031800; // CSI +const TUint KHwCSI0Phys = 0x18031400; +const TUint KHwSPDIFPhys = 0x18031000; // SPDIF +const TUint KHwSDPhys = 0x18030000; // SD + +// Taken from the NE1-TB Hardware Specification "NE1-TB_HW-Spec_R1p0_20071221.pdf" +// Section 5 +const TUint KHwFPGAPhys = 0x04010000; // FPGA registers + +// Taken from an email Section 4 and email exchange with NEC +const TUint KHwLANPhys = 0x04000000; // SMCS 9118 LAN Controller + + +//---------------------------------------------------------------------------- +// Memory map: linear addresses +// This has to be consistent with HwBanks mappings in bootrom (see, ne1_tb.s). +//---------------------------------------------------------------------------- +#ifdef __MEMMODEL_DIRECT__ + +const TUint KHwBaseUart0 = KHwUART0Phys; // serial port #0 +const TUint KHwBaseMPCorePrivate = KHwBaseMPcorePrivatePhys; // 4KB of private MPcore region for SCU and Interrupt controller +const TUint KHwTimersBase = KHwTimer0Phys; // six SoC timers +const TUint KHwDisplayBase = KHwDispPhys; // SoC display controller +const TUint KHwBaseI2C = KHwI2CPhys; // I2C +const TUint KHwFPGABase = KHwFPGAPhys; // FPGA registers +const TUint KHwSPDIFBase = KHwSPDIFPhys; // SPDIF +const TUint KHwBaseSDCtrl = KHwSDPhys; // SD +const TUint KDMACExBusBase = KHwAHBEXDMACPhys; // DMAC(4C) 4KB +const TUint KDMAC32Base = KHwAHB0DMAC0Phys; // DMAC(8C) 20KB +const TUint KHwDMAC64Base = KHwAXI64DMACPhys; // DMAC(4C) 4KB on AXI bus - 64bit +const TUint KHwBaseEthernet = KHwLANPhys; // Ethernet +const TUint KHwGPIOBase = KHwGPIOPhys; // GPIO +const TUint KHwPciBase = KHwAHB32PCI_ExtPhys; // PCI Bridges +const TUint KHwUsbHWindow = KHwUSBHPhys; // Internal PCI window +//const TUint KHw xxx Base = KHw xxx Phys; // xxx + +#else + +const TLinAddr KHWIOBase = 0xC6000000u; // Base address of virtual address range used for HW mappings + +const TUint KHwBaseUart0 = KHWIOBase; //Bank # 0, ofset 0, size 4K // serial port #0 ///< Internal, clients get value from HCR +const TUint KHwBaseMPCorePrivate = KHWIOBase + 0x01000; //Bank # 1, offset 1000h, size 2*4K // 4KB of private MPcore region for SCU and Interrupt controller ///< Internal, clients get value from HCR +const TUint KHwTimersBase = KHWIOBase + 0x03000; //Bank # 2, offset 3000h, size 2*K // six SoC timers ///< Internal, clients get value from HCR +const TUint KHwDisplayBase = KHWIOBase + 0x05000; //Bank # 3, offset 4000h, size 4*K // SoC display controller ///< Internal, clients get value from HCR +const TUint KHwBaseI2C = KHWIOBase + 0x09000; //Bank # 4, offset 9000h, size 2*4K // I2C ///< Internal, clients get value from HCR +const TUint KHwFPGABase = KHWIOBase + 0x0B000; //Bank # 5, offset B000h, size 4K // FPGA registers ///< Internal, clients get value from HCR +const TUint KHwSPDIFBase = KHWIOBase + 0x0C000; //Bank # 6, offset C000h, size 4K // SPDIF ///< Internal, clients get value from HCR +const TUint KHwBaseSDCtrl = KHWIOBase + 0x0D000; //Bank # 7, offset D000h, size 4K // SD ///< Internal, clients get value from HCR +const TUint KDMACExBusBase = KHWIOBase + 0x0E000; //Bank # 8, offset D000h, size 6*4K = 24K // DMAC(4C) 4KB ///< Internal, clients get value from HCR +const TUint KDMAC32Base = KHWIOBase + 0x0F000; //Bank # 9, offset D000h, size 6*4K = 24K // DMAC(8C) 20KB ///< Internal, clients get value from HCR +const TUint KHwBaseEthernet = KHWIOBase + 0x14000; //Bank #10, offset 14000h, size 4K // Ethernet ///< Internal, clients get value from HCR +const TUint KHwGPIOBase = KHWIOBase + 0x15000; //Bank #11, offset 15000h, size 4K // GPIO ///< Internal, clients get value from HCR +const TUint KHwPciBase = KHWIOBase + 0x16000; //Bank #12, offset 16000h, size 2*4K // PCI Bridges ///< Internal, clients get value from HCR +const TUint KHwUsbHWindow = KHWIOBase + 0x18000; //Bank #13, offset 18000h, size 2*4K // Internal PCI window ///< Internal, clients get value from HCR +const TUint KHwDMAC64Base = KHWIOBase + 0x1A000; //Bank #14, offset 1A000h, size 4k // DMAC(4C) 4KB on AXI bus - 64bit ///< Internal, clients get value from HCR +//const TUint KHw xxx Base = KHWIOBase + 0x1B000; //Bank #15, offset 1B000h, size xK // xxx ///< Internal, clients get value from HCR +#endif + + + + +const TUint KHwBaseUart1 = KHwBaseUart0 + 0x400; // serial port #1 ///< Internal, clients get value from HCR +const TUint KHwBaseUart2 = KHwBaseUart0 + 0x800; // serial port #2 ///< Internal, clients get value from HCR +const TUint KHwBaseSCU = KHwBaseMPCorePrivate; // Snoop Control Unit ///< Internal, clients get value from HCR +const TUint KHwBaseIntIf = KHwBaseMPCorePrivate + 0x100; // CPU interrupt interface ///< Internal, clients get value from HCR +const TUint KHwBaseGlobalIntDist = KHwBaseMPCorePrivate + 0x1000; // Global Interrupt Distributer ///< Internal, clients get value from HCR +const TUint KHwWatchdog = KHwTimersBase + 0x1800; // eWDT (Watchdog Timer) ///< Internal, clients get value from HCR +const TUint KHwSystemCtrlBase = KHwTimersBase + 0x1c00; // system control unit ///< Internal, clients get value from HCR +const TUint KHwBaseI2S0 = KHwBaseI2C + 0x400; // I2S0 ///< Internal, clients get value from HCR +const TUint KHwBaseI2S1 = KHwBaseI2S0 + 0x400; // I2S1 ///< Internal, clients get value from HCR +const TUint KHwBaseI2S2 = KHwBaseI2S0 + 0x800; // I2S2 ///< Internal, clients get value from HCR +const TUint KHwBaseI2S3 = KHwBaseI2S0 + 0xC00; // I2S3 ///< Internal, clients get value from HCR +const TUint KHwBaseCSI0 = KHwSPDIFBase + 0x400; // CSI0 ///< Internal, clients get value from HCR +const TUint KHwBaseCSI1 = KHwBaseCSI0 + 0x400; // CSI1 ///< Internal, clients get value from HCR +const TUint KHwLCDDispBase = KHwFPGABase + 0x0400; // LCD display ///< Internal, clients get value from HCR +const TUint KHwTSPBase = KHwFPGABase + 0x0600; // Digitiser ///< Internal, clients get value from HCR +const TUint KHwPciBridgeExtern = KHwPciBase; // External PCI Bridge ///< Internal, clients get value from HCR +const TUint KHwPciBridgeUsb = KHwPciBase + 0x1000; // UsbHost dedicated PCI Bridge ///< Internal, clients get value from HCR + + + +//---------------------------------------------------------------------------- +// CPU interrupt interface registers' addresses. +//---------------------------------------------------------------------------- +const TUint KHwCIIControl = KHwBaseIntIf + 0x00; // Control +const TUint KHwCIIPrioMask = KHwBaseIntIf + 0x04; // Priority mask +const TUint KHwCIIBinPoint = KHwBaseIntIf + 0x08; // Binary point +const TUint KHwCIIIntAck = KHwBaseIntIf + 0x0C; // Interrupt acknowledge RO +const TUint KHwCIIEndOfInt = KHwBaseIntIf + 0x10; // End of interrupt WO +const TUint KHwCIIPrioRun = KHwBaseIntIf + 0x14; // Running Interrupt RO +const TUint KHwCIIHighPend = KHwBaseIntIf + 0x18; // Highest pending interrupt RO + +const TUint KHoCIIIntAck = 0x0C; // Interrupt acknowledge RO +const TUint KHoCIIEndOfInt = 0x10; // End of interrupt WO + +//---------------------------------------------------------------------------- +// Global Interrupt Distributor registers' addresses +//---------------------------------------------------------------------------- +const TUint KHoGidControl = KHwBaseGlobalIntDist + 0x000; // Control Register. Holds enable bit. +const TUint KHoGidType = KHwBaseGlobalIntDist + 0x004; // Controller type. Read only register +const TUint KHoGidIntEnableBase = KHwBaseGlobalIntDist + 0x100; // Writing into these registers will enable appropriate interrupt(s), 1 bit per interrupt +const TUint KHoGidIntDisableBase = KHwBaseGlobalIntDist + 0x180; // Writing into these registers will disable appropriate interrupt(s), 1 bit per interrupt +const TUint KHoGidPendSetBase = KHwBaseGlobalIntDist + 0x200; // Writing into these registers will return appropriate interrupt(s) from Pending to Inactive state. Active state is not modified, 1 bit per interrupt +const TUint KHoGidPendClearBase = KHwBaseGlobalIntDist + 0x280; // Writing into these registers will put appropriate interrupt(s) into Pending state, 1 bit per interrupt +const TUint KHoGidActiveBase = KHwBaseGlobalIntDist + 0x300; // Indicates if corresponding interrupt is active. Ints 0-31 (the first reg.) are aliased for each CPU, 1 bit per interrupt +const TUint KHoGidPriorityBase = KHwBaseGlobalIntDist + 0x400; // Priority of the interrupts, 8 bits per int, only 4 used +const TUint KHoGidTargetBase = KHwBaseGlobalIntDist + 0x800; // Interrupt CPU targets, 8 bits per int, only 4 used +const TUint KHoGidConfigBase = KHwBaseGlobalIntDist + 0xC00; // Interrupt configuration register: edge or leveled; 1-N or N-N software model, 2 bits per interrupt +const TUint KHoGidSoftwareTrigger = KHwBaseGlobalIntDist + 0xF00; // Software interrupt Trigger Register. A single register for all ints. + +//---------------------------------------------------------------------------- +// SystemControlUnit registers' addresses +//---------------------------------------------------------------------------- +const TUint KHoSCUClockMaskCtrl = 0x80; // Mask control +const TUint KHoSCUDisplayDCLKCtrl = 0x8c; // Display DCLK control +const TUint KHw60HzDisplay = 11; + +// Divide I2S CLK Control Register +const TUint KHoSCUDivideI2SCLKCtrl = 0x94; +const TUint KHtSCUDivI2SCLKCtrl_I2S0MCLK_SEL = (1<<4); // Selects the I2S0 MCLK source: 1-SPDIF, 0-external input. +const TUint KHsSCUDivI2SCLKCtrl_I2S0MCLK_FREQ = 0; // shift for the MCK clock frequency for I2S0 unit +const TUint KHsSCUDivI2SCLKCtrl_I2S1MCLK_FREQ = 8; // shift for the MCK clock frequency for I2S1 unit +const TUint KHsSCUDivI2SCLKCtrl_I2S2MCLK_FREQ = 16; // shift for the MCK clock frequency for I2S2 unit +const TUint KHsSCUDivI2SCLKCtrl_I2S3MCLK_FREQ = 24; // shift for the MCK clock frequency for I2S3 unit +// values for MCK clock frequency +const TUint KHSCUDivI2SCLKCtrl_I2SMCLK_FREQ36_864M = 0; +const TUint KHSCUDivI2SCLKCtrl_I2SMCLK_FREQ24_576M = 1; +const TUint KHSCUDivI2SCLKCtrl_I2SMCLK_FREQ18_432M = 2; +const TUint KHSCUDivI2SCLKCtrl_I2SMCLK_FREQ33_8688M = 4; +const TUint KHSCUDivI2SCLKCtrl_I2SMCLK_FREQ22_5792M = 5; +const TUint KHSCUDivI2SCLKCtrl_I2SMCLK_FREQ16_9344M = 6; + +//---------------------------------------------------------------------------- +// I2S Register Addresses +//---------------------------------------------------------------------------- +const TUint KHoI2SCtrl = 0x00; // I2S Control register offset +const TUint KHtI2SCtrl_MSMODE = (1<<28); // master/slave mode (1-master, 0-slave) +const TUint KHtI2SCtrl_TEN = (1<<25); // transmission enable (1-enable, 0-disable) +const TUint KHtI2SCtrl_REN = (1<<24); // reception (1-enable, 0-disable) +const TUint KHsI2SCtrl_FCKLKSEL = 16; // [3:0] clock select mask (Sampling fq) +const TUint KHsI2SCtrl_FSMODE = 12; // [1:0] number of SCLK cycles in one frame (1WS cycle) +const TUint KHsI2SCtrl_FORMAT = 8; // [2:0] transfer format (I2S = 100b) +const TUint KHtI2SCtrl_INVALID = (1<<6); // Invalid data format(1 - outputs "1" as invalid data) +const TUint KHsI2SCtrl_DLENGTH = 0; // [4:0] sampling data length + +const TUint KHoI2SFifoCtrl = 0x04; // I2S Fifo Control register offset +const TUint KHtI2SFifoCtrl_TDMAEN = (1<<23); // Enables DMA req on transmit side +const TUint KHtI2SFifoCtrl_TFIFOCLR = (1<<22); // transmit FIFO initialisation +const TUint KHsI2SFifoCtrl_TFIFOLT = 19; // [2:0] L-ch transmit FIFO trigger level (0-3: 2-16 word space avl) +const TUint KHsI2SFifoCtrl_TFIFORT = 16; // [2:0] R-ch transmit FIFO trigger level (0-3: 2-16 word space avl) +const TUint KHtI2SFifoCtrl_RDMAEN = (1<<7); // Enables DMA req on receive side +const TUint KHtI2SFifoCtrl_RFIFOCLR = (1<<6); // receive FIFO initialisation +const TUint KHsI2SFifoCtrl_RFIFOLT = 3; // [2:0] L-ch receive FIFO-full trigger level (0-3: 2-16 word space avl) +const TUint KHsI2SFifoCtrl_RFIFORT = 0; // [2:0] R-ch receive FIFO-full trigger level (0-3: 2-16 word space avl) + +const TUint KHoI2SFifoSts = 0x08; // I2S Fifo status register offset +const TUint KHtI2SFifoSts_TFL_FULL = (1<<17); // L-ch transmit FIFO full (32 words) +const TUint KHtI2SFifoSts_TFR_FULL = (1<<16); // R-ch transmit FIFO full (32 words) +const TUint KHtI2SFifoSts_RFL_EMPTY = (1<<1); // L-ch receive FIFO empty +const TUint KHtI2SFifoSts_RFR_EMPTY = (1<<0); // R-ch receive FIFO empty + +const TUint KHoI2SIntFlg = 0x0C; // I2S interrupt flag register offset +const TUint KHtI2SIntFlg_TFLURINT = (1<<19); // L-ch transmit FIFO underrun +const TUint KHtI2SIntFlg_TFLEINT = (1<<18); // L-ch transmit FIFO reached the empty trigger level +const TUint KHtI2SIntFlg_TFRURINT = (1<<17); // R-ch transmit FIFO underrun +const TUint KHtI2SIntFlg_TFREINT = (1<<16); // R-ch transmit FIFO reached the empty trigger level +const TUint KHtI2SIntFlg_RFLORINT = (1<<3); // L-ch receive FIFO overrun +const TUint KHtI2SIntFlg_RFLFINT = (1<<2); // L-ch receive FIFO reached the full trigger level +const TUint KHtI2SIntFlg_RFRORINT = (1<<1); // R-ch receive FIFO overrun +const TUint KHtI2SIntFlg_RFRFINT = (1<<0); // R-ch receive FIFO reached the full trigger level + +const TUint KHoI2SIntMask = 0x10; // I2S interrupt mask register offset +const TUint KHtI2SIntMask_TFLURINT = (1<<19); // L-ch transmit FIFO underrun int enable +const TUint KHtI2SIntMask_TFLEINT = (1<<18); // L-ch transmit FIFO reached the empty trigger level int enable +const TUint KHtI2SIntMask_TFRURINT = (1<<17); // R-ch transmit FIFO underrun int enable +const TUint KHtI2SIntMask_TFREINT = (1<<16); // R-ch transmit FIFO reached the empty trigger level int enable +const TUint KHtI2SIntMask_RFLORINT = (1<<3); // L-ch receive FIFO overrun int enable +const TUint KHtI2SIntMask_RFLFINT = (1<<2); // L-ch receive FIFO reached the full trigger level int enable +const TUint KHtI2SIntMask_RFRORINT = (1<<1); // R-ch receive FIFO overrun int enable +const TUint KHtI2SIntMask_RFRFINT = (1<<0); // R-ch receive FIFO reached the full trigger level int enable +const TUint KHmI2SIntMask_ALL = 0xF000F; // All interrupts mask + +const TUint KHoI2SRx = 0x20; // I2S receive data FIFO register offset +const TUint KHoI2STx = 0x30; // I2S transmit data FIFO register offset + +//---------------------------------------------------------------------------- +//FPGA Register Addresses +//---------------------------------------------------------------------------- +const TUint KHoLCDControl = 0x400; +const TUint KHoSystemPowerDown = 0xF10; + +const TUint KHwIDMODE = KHwFPGABase+0x0810; +const TUint KHmUserSwitches = 0x3C00; +const TUint KHsUserSwitches = 10; +const TUint KHmLcdSwitches = 0x3000; +const TUint KHsLcdSwitches = 12; +const TUint KHmKeyConfigSwitch = 0x800; +const TUint KHsKeyConfigSwitch = 11; + +// There are 4 red LEDs that can be controlled by the FPGA +// Each LED has a bit in the register, where 0==off and 1==on +const TUint KHoFpgaLeds = 0x0A06; +const TUint KHwFpgaLeds = KHwFPGABase+KHoFpgaLeds; + +const TUint KHmFpgaLeds = 0xF; + +const TUint KHsFpgaLed0 = 0x0; +const TUint KHsFpgaLed1 = 0x1; +const TUint KHsFpgaLed2 = 0x2; +const TUint KHsFpgaLed3 = 0x3; + +const TUint KHtFpgaLed0 = 1 << KHsFpgaLed0; +const TUint KHtFpgaLed1 = 1 << KHsFpgaLed1; +const TUint KHtFpgaLed2 = 1 << KHsFpgaLed2; +const TUint KHtFpgaLed3 = 1 << KHsFpgaLed3; + +//---------------------------------------------------------------------------- +//CSI Register Addresses +//---------------------------------------------------------------------------- +const TUint KHoCSIModeControl = 0x00; // CSI Mode Control Register +const TUint KHsCSIModeTWait = 16; // CSI waiting time for transaction shift +const TUint KHtCSIModeEnable = 1<<7; // CSI enable +const TUint KHtCSIModeTrEnable = 1<<6; // CSI transmission and reception mode select +const TUint KHtCSIModeDataLen = 1<<5; // CSI Data length select: 0-8bits, 1-16bits +const TUint KHtCSIModeTransferDir = 1<<4; // CSI Transfer direction mode: 0-MSB first, 1-LSB first +const TUint KHtCSIModeTransferState = 1<<0; // CSI Transfer state indication flag: 0-idle first, 1-transmission + +const TUint KHoCSIClockSelect = 0x04; // CSI Clock Select Register +const TUint KHtCSIClockSelectSSE = 1<<9; // SS pin enable +const TUint KHtCSIClockSelectSSPol = 1<<8; // SS pin polarity select (0: SS pin low active, 1: SS pin high active) +const TUint KHtCSIClockSelectCKP = 1<<4; // Clock polarity select +const TUint KHtCSIClockSelectDAP = 1<<3; // Clock phase select + +const TUint KHsCSIClockSelect = 0; // Communication clock select shift CKS[2:0] +const TUint KHCSIClockValPCLKdiv4 = 0; // 1/4 PCLK (master mode) 16.67 MHz +const TUint KHCSIClockValPCLKdiv16 = 1; // 1/16 PCLK (master mode) 4.17 MHz +const TUint KHCSIClockValPCLKdiv32 = 2; // 1/32 PCLK (master mode) 2.08 MHz +const TUint KHCSIClockValPCLKdiv64 = 3; // 1/64 PCLK (master mode) 1.04 MHz +const TUint KHCSIClockValPCLKdiv128 = 4; // 1/128 PCLK (master mode) 521 kHz +const TUint KHCSIClockValPCLKdiv256 = 5; // 1/256 PCLK (master mode) 260 kHz +const TUint KHCSIClockValPCLKdiv512 = 6; // 1/512 PCLK (master mode) 130 kHz +const TUint KHCSIClockValSlave = 7; // SCKI (slave mode) + +const TUint KHoCSIControl = 0x08; // CSI Control Register +const TUint KHtCSIControlCSIRst = 1<<28; // CSI unit reset +const TUint KHtCSIControlTxTrgEn = 1<<27; // Permission of CSI_FIFOTRG.bit10-8(T_TRG[2:0]) operation +const TUint KHtCSIControlTxFifoFull = 1<<26; // State of Tx FIFO buffer +const TUint KHtCSIControlTxDMAE = 1<<24; // Tx DMA mode +const TUint KHtCSIControlSSMon = 1<<21; // SS signal monitor +const TUint KHtCSIControlRxTrgEn = 1<<19; // Permission of CSI_FIFOTRG.bit2-0(R_TRG[2:0]) operation +const TUint KHtCSIControlRxFifoFull = 1<<18; // State of Rx FIFO buffer +const TUint KHtCSIControlRxDMAE = 1<<16; // Rx DMA mode + +const TUint KHtCSIControlSSDnIE = 1<<15; // SS signal negative-edge interrupt (CSI_INT.bit15(SS_DN)) enable +const TUint KHtCSIControlSSUpIE = 1<<14; // SS signal positive-edge interrupt (CSI_INT.bit14(SS_UP)) enable +const TUint KHtCSIControlTxUndIE = 1<<13; // Tx FIFO buffer under-run error interrupt (CSI_INT.bit13(UNDER)) enable +const TUint KHtCSIControlRxOvfIE = 1<<12; // Rx FIFO buffer overflow error interrupt (CSI_INT.bit12(OVERF)) enable +const TUint KHtCSIControlTEndIE = 1<<8; // Transmission end interrupt (CSI_INT.bit8(CSIEND)) enable +const TUint KHtCSIControlTxTrgIE = 1<<4; // Tx trigger level interrupt (CSI_INT.bit4(T_TRGR)) enable +const TUint KHtCSIControlRxTrgIE = 1<<0; // Rx trigger level interrupt (CSI_INT.bit0(R_TRGR bit) enable + +const TUint KHoCSIIntStatus = 0x0C; // CSI Interrupt Status Register +const TUint KHtCSIIntStatusSSDn = 1<<15; // SS signal negative-edge interrupt +const TUint KHtCSIIntStatusSSUp = 1<<14; // SS signal positive-edge interrupt +const TUint KHtCSIIntStatusTxUnd = 1<<13; // Tx FIFO buffer under-run error interrupt +const TUint KHtCSIIntStatusRxOvf = 1<<12; // Rx FIFO buffer overflow error interrupt +const TUint KHtCSIIntStatusTEnd = 1<<8; // Transmission end interrupt +const TUint KHtCSIIntStatusTxTrgIE = 1<<4; // Tx trigger level interrupt +const TUint KHtCSIIntStatusRxTrgIE = 1<<0; // Rx trigger level interrupt + +const TUint KHoCSIIFifoL = 0x10; // CSI Receive FIFO level indicate Register +const TUint KHoCSIOFifoL = 0x14; // CSI Transmit FIFO level indicate Register +const TUint KHoCSIIFifo = 0x18; // CSI Receive FIFO Window Register +const TUint KHoCSIOFifo = 0x1C; // CSI Transmit FIFO Window Register +const TUint KHwCSIFifoLMax = 32; // maximum amount of data in the CSI FIFO + +const TUint KHoCSIFifoTrgLvl = 0x20; // CSI FIFO Trigger Level Register +const TUint KHsCSITxFifoTrgLvl = 8; // transmit FIFO trigger level shift [10:8] +const TUint KHsCSIRxFifoTrgLvl = 0; // receive FIFO trigger level shift [2:0] + +//---------------------------------------------------------------------------- +// GPIO Register Addresses +//---------------------------------------------------------------------------- +const TUint KHwRwGpio_Port_Control_Enable = KHwGPIOBase + 0x00; +const TUint KHwWoGpio_Port_Control_Disable = KHwGPIOBase + 0x04; +const TUint KHwWoGpio_Port_Set_Clear_Hi = KHwGPIOBase + 0x08; +const TUint KHwWoGpio_Port_Set_Clear_Lo = KHwGPIOBase + 0x0c; +const TUint KHwRoGpio_Port_Value = KHwGPIOBase + 0x10; +const TUint KHwRwGpio_Int = KHwGPIOBase + 0x14; +const TUint KHwRwGpio_Int_Enable = KHwGPIOBase + 0x18; +const TUint KHwWoGpio_Int_Disable = KHwGPIOBase + 0x1c; +const TUint KHwRwGpio_Int_Hold = KHwGPIOBase + 0x20; +const TUint KHwRwGpio_Int_Mode0 = KHwGPIOBase + 0x24; +const TUint KHwRwGpio_Int_Mode1 = KHwGPIOBase + 0x28; +const TUint KHwRwGpio_Int_Mode2 = KHwGPIOBase + 0x2c; +const TUint KHwRwGpio_Int_Mode3 = KHwGPIOBase + 0x30; +const TUint KHwRwGpi_Polarity_Invert = KHwGPIOBase + 0x38; +const TUint KHwWoGpi_Polarity_Reset = KHwGPIOBase + 0x3c; +const TUint KHwRwGpo_Polarity_Invert = KHwGPIOBase + 0x40; +const TUint KHwWoGpo_Polarity_Reset = KHwGPIOBase + 0x44; + +const TUint KGpio_Ethernet_Int_Pin = 20; + +//---------------------------------------------------------------------------- +// eWDT Register Addresses +//---------------------------------------------------------------------------- +const TUint KHwWatchdog_WDTCNT (KHwWatchdog + 0); // Control register +const TUint KHwWatchdog_WDTSET (KHwWatchdog + 4); // Period setting register +const TUint KHwWatchdog_WDTTIM (KHwWatchdog + 8); // Lapsed time register +const TUint KHwWatchdog_WDTINT (KHwWatchdog + 12); // Interrupt register + +//---------------------------------------------------------------------------- +// Baud Rate Divisor values +//---------------------------------------------------------------------------- +const TUint KBaudRateDiv_50 = 0; +const TUint KBaudRateDiv_75 = 0; +const TUint KBaudRateDiv_110 = 0; +const TUint KBaudRateDiv_134 = 0; +const TUint KBaudRateDiv_150 = 55417; +const TUint KBaudRateDiv_300 = 27708; +const TUint KBaudRateDiv_600 = 13854; +const TUint KBaudRateDiv_1200 = 6927; +const TUint KBaudRateDiv_1800 = 4618; +const TUint KBaudRateDiv_2000 = 4156; +const TUint KBaudRateDiv_2400 = 3464; +const TUint KBaudRateDiv_3600 = 2309; +const TUint KBaudRateDiv_4800 = 1732; +const TUint KBaudRateDiv_7200 = 1155; +const TUint KBaudRateDiv_9600 = 866; +const TUint KBaudRateDiv_19200 = 433; +const TUint KBaudRateDiv_38400 = 216; +const TUint KBaudRateDiv_57600 = 144; +const TUint KBaudRateDiv_115200 = 72; +const TUint KBaudRateDiv_230400 = 36; + +const TUint KBaudRateDiv_default = 72; // Set to KBaudRateDiv_115200 but h2inc.pl doesn't support token replacement. + +//---------------------------------------------------------------------------- +// Memory Layout addresses for BootLoader / bootstrap interaction +//---------------------------------------------------------------------------- + +const TUint KRamTargetAddr = 0x88000000; // Phys. addr. of the image to be started by bootloader. +const TUint KCoreLoaderAddress = 0x8D000000; // base of ram + 208MB + +const TUint xKMega = (1024*1024); // we can't use KMega because h2inc won't resolve tokens from other includes +const TLinAddr KNORFlashTargetAddr = 0x00000000; // Onboard NOR flash starts at phys addr 0x0 +const TLinAddr KNORFlashTargetSize = ( 64 * xKMega); // and is 64MB is size +const TLinAddr KRamTargetSize = (128 * xKMega); // Reserved RAM starts at phys addr 0x88000000 and is 128MB is size + +// The layout of the onboard NOR is +// [bootloader][configblock][flashedimage][reserved] +const TLinAddr KNORFlashMaxBootloaderSize = (5 * xKMega); +const TLinAddr KNORFlashMaxImageSize = KNORFlashTargetSize - KNORFlashMaxBootloaderSize; + +//---------------------------------------------------------------------------- +// Restart Reason Codes +//---------------------------------------------------------------------------- + +// Restart types (bits 31-29) +const TUint KmRestartReasonsActions = 0xE0000000; // Bits 31 to 29 + +// These three bits are indications for the bootloader to perform some activity +const TUint KtRestartReasonHardRestart = 0x80000000; // Bit31 back to bootloader +const TUint KtRestartReasonSoftRestart = 0x40000000; // Bit30 back to same image (will need image location too) +const TUint KtRestartReasonBootRestart = 0x20000000; // Bit29 back into new image (will need image location too) + +// This bit is an indicator for ane image to detect it is being warm booted +const TUint KtRestartReasonWarmBoot = 0x10000000; // Bit28 this boot is "warm" + +// Image locations (bits 27-20) +const TUint KmRestartImageLocations = 0x0FF00000; // Bits 27 to 20 +const TUint KtRestartReasonRAMImage = 0x08000000; // Bit27 +const TUint KtRestartReasonNORImage = 0x04000000; // Bit26 +const TUint KtRestartReasonNANDImage = 0x02000000; // Bit25 +const TUint KtRestartReasonONENANDImage = 0x01000000; // Bit24 +const TUint KtRestartReasonSIBLEYImage = 0x00800000; // Bit23 +const TUint KtRestartReasonOTAUpgrade = 0x00400000; // Bit22 +const TUint KtRestartReasonCoreLdr = 0x00200000; // Bit21 This platform specific reason introduced to start SMP enabled CoreLdr + +// Restart startup Mode (bits 19-16) +const TUint KmRestartStartupModes = 0x000F0000; // Bits 19 to 16 +const TUint KsRestartStartupModes = 16; +const TUint KRestartStartupModesSize = 4; // size in bits + +// Custom restart reasons (bits 15-8) +const TUint KmRestartCustomRestartReasons = 0x0000FF00; // Bits 15 to 8 +const TUint KsRestartCustomRestartReasons = 8; +const TUint KRestartCustomRestartReasonsSize = 8; // size in bits + +// Define USB loader restart (after USB link dropped) +const TUint KtRestartCustomRestartUSBLoader = 0x00008000; // Bit 15 +const TUint KtRestartCustomRestartMemCheck = 0x00004000; // Bit 14 +const TUint KtRestartCustomRestartMemCheckPass = 0x00002000; // Bit 13 + +// Mask of all the bits used during the memory test (but not the start) +const TUint KmRestartCustomRestartMemCheckBits = 0x00003F00; // Bits 13 to 8 + + +// Gap (bits 7-0) + +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/naviengine.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/naviengine.inf Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp/naviengine.inf +* +*/ + + + +PRJ_PLATFORMS +ARM4 ARMV5 + +PRJ_EXPORTS + +naviengine.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/) +naviengine.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/direct/) +naviengine.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/multiple/) +naviengine.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/flexible/) +naviengine_priv.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/) +navienginedma.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/) +variant_timestamp.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/nkern/) +highrestimer.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/nkern/) +naviengine_lcd.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/) +upd35001_timer.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/) +watchdog.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/) +pci/pci.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/) +hcr/hcrconfig_assp.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/) +// Exports of private internal component settings for HCR so the 3 NE1 variants +// when building HCR can find this file. +csi/hcrconfig_csi.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/) + + +staticextension.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/) +staticextension.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/nkern/) + +#if !defined(GCCXML) || !defined(NO_GCCXML) + +PRJ_MMPFILES +kanaviengine +dma +dma_v2 +usbcc +uart/uart.mmp +uart/vserialkeyb.mmp +uart/ubootldrkeyb.mmp +pci/pci.mmp + +PRJ_TESTMMPFILES +pci/pci-test.mmp + +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/naviengine_assp.cia --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/naviengine_assp.cia Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\naviengine.cia +* NE1_TBVariant ASSP architecture layer +* +*/ + + + +#include +#include + +EXPORT_C __NAKED__ void TNaviEngine::BootWaitMilliSeconds(TInt aDuration) +// +// Active waiting loop (not to be used after System Tick timer has been set up - Init3() +// + { + // + // TO DO: (optional) + // + // Program a Hardware Timer to generate the required duration, and then loop until the timer expires. + // Do NOT use interrupts! + // + } + + +__NAKED__ void TNaviEngine::NanoWait(TUint32 aInterval) +// +// Wait for aInterval nanoseconds +// + { + // TO DO: work out the correct values for the hardware + + asm("subs r0, r0, #100 "); + asm("1:"); + asm("subhis r0, r0, #5 "); // 400MHz, 2 cycles = 5ns + asm("bhi 1b"); + __JUMP(,lr); + } diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/naviengine_assp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/naviengine_assp.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,172 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\naviengine.cpp +* +*/ + + + +#include +#include "uart/uart16550_ne.h" + +//---------------------------------------------------------------------------- +// Initialisation + +void TNaviEngine::Init1() +// +// Phase 1 initialisation +// + { + // Use assp-specific nano wait implementation + Kern::SetNanoWaitHandler(&NanoWait); + } + +void TNaviEngine::Init3() +// +// Phase 3 initialisation +// + { + // + // TO DO: (optional) + // + // Initialise any TNaviEngine class data members here + // + } + +EXPORT_C TMachineStartupType TNaviEngine::StartupReason() +// +// Read and return the Startup reason of the Hardware +// + { + // + // TO DO: (optional) + // + // Read the Reset reason from the hardware register map it to one of TMachineStartupType enumerated values + // and return this + // + return EStartupCold; // EXAMPLE ONLY + } + +EXPORT_C TInt TNaviEngine::CpuVersionId() +// +// Read and return the the CPU ID +// + { + // + // TO DO: (optional) + // + // Read the CPU identification register (if one exists) mask off redundant bits and return this + // + return 0; // EXAMPLE ONLY + } + +EXPORT_C TUint TNaviEngine::DebugPortAddr() +// +// Return Linear base address of debug UART (as selected in obey file or with eshell debugport command). +// + { + TUint debugPort; + switch (Kern::SuperPage().iDebugPort) + { + case Arm::EDebugPortJTAG: debugPort = 0; break; //indicates JTAG debugging + case 0x101: + case 1: debugPort=KHwBaseUart1; break; + case 2: debugPort=KHwBaseUart2; break; + default: debugPort=KHwBaseUart0; break; + } + return debugPort; + } + +EXPORT_C TUint TNaviEngine::ProcessorPeriodInPs() +// +// Return CPU clock period in picoseconds +// + { + // + // TO DO: (optional) + // + // Read the CPU clock speed and return its period in picoseconds. If only a limited range of speeds is possible + // it is preferable to use the masked speed reading as an index into a look up table containing the corresponding + // period + // + return 0; // EXAMPLE ONLY + } + +EXPORT_C TUint TNaviEngine::RtcData() +// +// Return the current time of the RTC +// + { + // + // TO DO: (optional) + // + // Read the RTC current time register and return this time + // + return 0; // EXAMPLE ONLY + } + +EXPORT_C void TNaviEngine::SetRtcData(TUint aValue) +// +// Set the RTC time +// + { + // + // TO DO: (optional) + // + // Set the RTC current time with aValue (may need formatting appropriately) + // + } + +EXPORT_C TPhysAddr TNaviEngine::VideoRamPhys() +// +// Return the physical address of the video RAM +// + { + return NaviEngineAssp::VideoRamPhys; + } + + + +void TNaviEngine::InitDebugOutput() + { + TUint baseAddr = DebugPortAddr(); + if (baseAddr) //baseAddr is NULL in case og jtag logging + { + TUint32 dp = Kern::SuperPage().iDebugPort; + TBool highSpeed = (dp==0x100 || dp==0x101); + + // Baud Rate = 115200 or 230400 (highspeed); 8 bits, no parity, 1 stop bit + *((volatile TInt*) (baseAddr+K16550LCROffset)) = 0x83; + *((volatile TInt*) (baseAddr+K16550BDLoOffset)) = highSpeed ? KBaudRateDiv_230400 : KBaudRateDiv_default; + *((volatile TInt*) (baseAddr+K16550BDHiOffset)) = 0; + *((volatile TInt*) (baseAddr+K16550LCROffset)) = 3; + } + } + +void TNaviEngine::DoDebugOutput(TUint aLetter) + { + TUint baseAddr = DebugPortAddr(); + if (baseAddr) + {//serial port logging + volatile TInt* status = (volatile TInt*) (baseAddr+K16550LSROffset); + while ((*status & K16550LSR_TXHREmpty) == 0); //wait till TXR is empty + *((volatile TInt*) (baseAddr+K16550TXHROffset)) = aLetter; + } + else + Arm::DebugOutJTAG((TUint8)aLetter); // jtag logging + } + + + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/naviengine_lcd.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/naviengine_lcd.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,314 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\naviengine_lcd.h +* +*/ + + + +#ifndef __NAVIENGINE_LCD_H__ +#define __NAVIENGINE_LCD_H__ +#include +#include +#include +#include +#include + + + +// Macro to calculate the screen buffer size +// aBpp is the number of bits-per-pixel, aPpl is the number of pixels per line and aLpp number of lines per panel +#define FRAME_BUFFER_SIZE(aBpp,aPpl,aLpp) (aBpp*aPpl*aLpp)/8 + + +//---------------------------------------------------------------------------- +//Display Controller registers +//---------------------------------------------------------------------------- + +// ------------------------------ +// Interface control registers +// ------------------------------ + +const TUint KHoDisplayInterfaceControl = 0x00; //!!! +const TUint KHwDisplayInterfaceControl = KHwDisplayBase + KHoDisplayInterfaceControl; + //DE - positive logic + //EVSYNC - negative logic + //VSYNC - negative logic + //EHSYNC - negative logic + //HSYNC - negative logic + //Dot clock normal polarity + //Switch on VSync, HSync, CSync, DEN + const TUint KInterfaceControlValue = 0x04; +const TUint KHoDisplayInterruptStatus = 0x08; +const TUint KHwDisplayInterruptStatus = KHwDisplayBase + KHoDisplayInterruptStatus; +const TUint KHoDisplayInterruptClear = 0x10; +const TUint KHwDisplayInterruptClear = KHwDisplayBase + KHoDisplayInterruptClear; +const TUint KHoDisplayInterruptEnable = 0x18; +const TUint KHwDisplayInterruptEnable = KHwDisplayBase + KHoDisplayInterruptEnable; +const TUint KHoDisplayInterruptLineSettings = 0x20; //??? +const TUint KHwDisplayInterruptLineSettings = KHwDisplayBase + KHoDisplayInterruptLineSettings; //??? + // ic_al_h??? +const TUint KHoDisplayInterruptEnableSelection = 0x28; +const TUint KHwDisplayInterruptEnableSelection = KHwDisplayBase + KHoDisplayInterruptEnableSelection; + + +// ------------------------------ +// Display control registers +// ------------------------------ + +const TUint KHoDisplayResolutionAndCycle = 0x30; //!!! +const TUint KHwDisplayResolutionAndCycle = KHwDisplayBase + KHoDisplayResolutionAndCycle; + //ds_hr[10:0] - Sets the horizontal (width) resolution. The valid range is 320 (QVGA) to 1280 (WXGA). + //ds_vr[25:16] - Sets the vertical (height) resolution. The valid range is 240 (QVGA) to 800 (WXGA). + //ds_th[42:32] - Sets HSYNC in dot clock units. ds_hr + 3 to 7FEh (7FFh is prohibited). + //ds_tv[57:48] - Sets VSYNC in line units. ds_vr + 3 to 3FEh (3FFh is prohibited). + + #define DISPLAY_RESOLUTION_AND_CYCLE(height, width, linesInFrame, pixelsInLine) (((height<<16) + width) | ((TUint64) ((linesInFrame<<16) + (pixelsInLine)) <<32)) + + +const TUint KHoDisplayPulseWidth = 0x38; //!!! +const TUint KHwDisplayPulseWidth = KHwDisplayBase + KHoDisplayPulseWidth; + //ds_thp[10:0] - Sets the HSYNC pulse width in dot clock units. Set these bits so that the total blank period is 3 clocks or more. + //ds_tvp[25:16] - Sets the VSYNC pulse width in line units. Set these bits so that the total blank period is 3H or more. + //ds_thb[42:32] - Sets the HSYNC back porch width in dot clock units. + //ds_tvb[57:48] - Sets the VSYNC back porch width in line units. + + //settings for LCD QVGA mode + // const TUint KPulseWidthLow = (3<<16)+25; // SW4-2 OFF + // const TUint KPulseWidthHigh = (3<<16)+38; // SW4-2 OFF + const TUint KPulseWidthLow = (2<<16)+25; // SW4-2 ON -on some VGA monitors it doesn't show the whole area + const TUint KPulseWidthHigh = (2<<16)+14; // SW4-2 ON + const TUint64 KPulseWidth = KPulseWidthLow | ((TUint64)KPulseWidthHigh <<32); + + //settings for Hitachi LCD VGA mode + const TUint KPulseWidthLowVgaLCD = (2<<16)+30; + const TUint KPulseWidthHighVgaLCD = 0x00020030; + const TUint64 KPulseWidthVgaLCD = KPulseWidthLowVgaLCD | ((TUint64)KPulseWidthHighVgaLCD <<32); + + //settings for NEC LCD WVGA mode + const TUint KPulseWidthLowWvga = (2<<16)+30; // RMH - xxx - magic numbers!!! + const TUint KPulseWidthHighWvga = 0x000A0000; // RMH - xxx - magic numbers!!! 0a seems to be a vertical offset, with 02 being too small and 21 being too large; the last two digits, now 00, were 30 seem to be the horizintal offset... + const TUint64 KPulseWidthWvga = KPulseWidthLowWvga | ((TUint64)KPulseWidthHighWvga <<32); + + //settings for VGA mode on monitor (if LCD panel is not present) + const TUint KPulseWidthLowVga = (2<<16)+96; + const TUint KPulseWidthHighVga = 0x00210030; + const TUint64 KPulseWidthVga = KPulseWidthLowVga | ((TUint64)KPulseWidthHighVga <<32); + +const TUint KHoDisplayDisplaySettings = 0x40; //!!! +const TUint KHwDisplaySettings = KHwDisplayBase + KHoDisplayDisplaySettings; + //ds_oc[0] - Sets on/off of display output to LCD panel; 0 - Off (Black output if sync signal is output); 1 - On + //gamma correction and dithering + const TUint KDisplaySettingsValue = 0x1; + + +const TUint KHoDisplayDithering = 0x48; +const TUint KHwDisplayDithering = KHwDisplayBase + KHoDisplayDithering; +const TUint KHoDisplayBrightness = 0x50; //!!! +const TUint KHwDisplayBrightness = KHwDisplayBase + KHoDisplayBrightness; + + //ds_bc[7:0] Sets the brightness coefficient for RGB data. The range is -128 to 127 (8 bits). To turn off brightness control, set to 0. + const TUint KDisplayBrightnessVal = 0x00; //!!! + +// ------------------------------ +// Memory Frame control registers +// ------------------------------ + +const TUint KHoDisplayEndianConversion = 0x58; //!!! +const TUint KHwDisplayEndianConversion = KHwDisplayBase + KHoDisplayEndianConversion; + + //mf_es0[1::0] - endian conversion of data in VRAM - should be 00b ??? + //mf_lbs[25:24] = 0 -limits of layers and dimensions + const TUint KEndianConversionValue = 0x00; //!!! + + +//mf_pf0[3:0] Sets the pixel format of each memory frame stored in VRAM. 0h: ARGB0565 +const TUint KHoDisplayPixelFormat = 0x60; //!!! +const TUint KHwDisplayPixelFormat = KHwDisplayBase + KHoDisplayPixelFormat; + +const TUint KPixelFormatValue16bpp = 0x0; // ARGB0565 +const TUint KPixelFormatValue32bpp = 0x4; // ARGB8888 +const TUint KPixelFormatValue = KPixelFormatValue32bpp; // Retain keyword and default to bpp32 + + +//mf_sa0[31:0] - Sets the start address of the memory frame stored in VRAM, in byte units. +//mf_sa1[63:32] - Sets the start address of the memory frame stored in VRAM, in byte units. +const TUint KHoDisplayMemoryFrameAddress = 0x0070; //!!! +const TUint KHwDisplayMemoryFrameAddress = KHwDisplayBase + KHoDisplayMemoryFrameAddress; + + +// physical address in VRAM +const TUint KHoDisplayColorPalletAddress = 0x90; +const TUint KHwDisplayColorPalletAddress = KHwDisplayBase + KHoDisplayColorPalletAddress; + + +const TUint KHoDisplayColorPalletDirection = 0xA0; +const TUint KHwDisplayColorPalletDirection = KHwDisplayBase + KHoDisplayColorPalletDirection; + +const TUint KHoDisplayMemoryFrameSizeH = 0xA8; //!!! +const TUint KHwDisplayMemoryFrameSizeH = KHwDisplayBase + KHoDisplayMemoryFrameSizeH; + + // mf_ws_h0[11:0] - horisontal(width) size in byte units. The valid setting range is 1 to 4,096 at 0 to 4,095. + + // Usually the width value - 1, eg for 640 pixels wide, use 639 + +const TUint KHoDisplayMemoryFrameSizeV = 0xB8; //!!! +const TUint KHwDisplayMemoryFrameSizeV = KHwDisplayBase + KHoDisplayMemoryFrameSizeV; + + // mf_ws_v0[11:0] - vertical(height) size in line units + + // Usually the height value - 1, eg for 480 pixels high, use 479 + +const TUint KHoDisplayMemoryFrameStartPointX = 0xc8; //!!! +const TUint KHwDisplayMemoryFrameStartPointX = KHwDisplayBase + KHoDisplayMemoryFrameStartPointX; +//mf_sp_x0[11:0] - Sets the horizontal-direction start point coordinates of the +// frame memory stored in VRAM, in pixel units + +const TUint KHoDisplayMemoryFrameStartPointY = 0xd8; //!!! +const TUint KHwDisplayMemoryFrameStartPointY = KHwDisplayBase + KHoDisplayMemoryFrameStartPointY; +//mf_sp_y0[11:0] - Sets the vertical-direction start point coordinates of the +// frame memory stored in VRAM, in line units. + +const TUint KHoDisplayMemoryFrameStartFractionV = 0xe8; +const TUint KHwDisplayMemoryFrameStartFractionV = KHwDisplayBase + KHoDisplayMemoryFrameStartFractionV; + +const TUint KHoDisplayMemoryFrameDisplayFrameSizeH = 0xf0; //!!! +const TUint KHwDisplayMemoryFrameDisplayFrameSizeH = KHwDisplayBase + KHoDisplayMemoryFrameDisplayFrameSizeH; + + //mf_ds_h0[11:0] - Sets display frame horizontal-direction size in the memory + // frame, in pixel units. The valid setting range is 1 to 1,280 at 0 to 1,279. + + // Usually the width value - 1, eg for 640 pixels wide, use 639 + + +const TUint KHoDisplayMemoryFrameDisplayFrameSizeV = 0x100; //!!! +const TUint KHwDisplayMemoryFrameDisplayFrameSizeV = KHwDisplayBase + KHoDisplayMemoryFrameDisplayFrameSizeV; + + //mf_ds_v0[11:0] - Sets display frame vertical-direction size in the memory + // frame, in line units. The valid setting range is 1 to 800 at 0 to 799. + + // Usually the height value - 1, eg for 480 pixels high, use 479 + + + +const TUint KHoDisplayBorderColourRGB = 0x110; //!!! +const TUint KHwDisplayBorderColourRGB = KHwDisplayBase + KHoDisplayBorderColourRGB; //!!! + + //!!! + //mf_bc0[23:0] - Sets the border color value. Correspondence of mf_bcX[23:0] is as shown in Figure 2-6-22. + //mf_bc_s0[28] - Sets the border color format for the corresponding layer. + // 0: Format set by mf_pf0 (memory frame pixel format) + // 1: ARGB0888 + + +// ------------------------------ +// Display frame control registers +// ------------------------------ + +// NOTE: KH*DisplayDisplay is done on purpose because KH*Display is the prefix and the next Display is part of the register name! + +const TUint KHoDisplayDisplayFrameControl = 0x130; //!!! +const TUint KHwDisplayDisplayFrameControl = KHwDisplayBase + KHoDisplayDisplayFrameControl; + //df_dc0[3:0] - Sets whether a layer is to be displayed according to a priority.7 - is off + //df_vs0[8] - Selects the contents of VRAM or register to be displayed. + // 0: VRAM + // 1: Register (Value of constant color (df_cc_r, df_cc_g, and df_cc_b) registers is displayed.) + //df_lc0[12] - Sets layer on/off. (Stops access to VRAM.) Display can be turned off by df_dc0, but + // access to VRAM is not stopped. To accurately turn off display, use this register + + // Values to set layers 0-3 frame control on and fix their priority. + const TUint64 KDisplayFrameControlValue = (1<<12); + const TUint64 KDisplayFrame1ControlValue = (1<<28) | (0x1<<16); + const TUint64 KDisplayFrame2ControlValue = ((TInt64)1<<44) | ((TInt64)0x2<<32) ; + const TUint64 KDisplayFrame3ControlValue = ((TInt64)1<<60) | ((TInt64)0x3<<48) ; + + +const TUint KHoDisplayDisplayFrameStartPointX = 0x140; //!!! +const TUint KHwDisplayDisplayFrameStartPointX = KHwDisplayBase + KHoDisplayDisplayFrameStartPointX; + //df_sp_x0[11:0] - Sets the horizontal-direction start point coordinates to be + // displayed, in pixel units. The valid setting range is -2,048 to 2,047. + +const TUint KHoDisplayDisplayFrameStartPointY = 0x150; //!!! +const TUint KHwDisplayDisplayFrameStartPointY = KHwDisplayBase + KHoDisplayDisplayFrameStartPointY; + //df_sp_y0[11:0] - Sets the vertical-direction start point coordinates to be + // displayed, in line units. The valid setting range is -2,048 to 2,047. + +const TUint KHoDisplayDisplayFrameSizeH = 0x160; //!!! +const TUint KHwDisplayDisplayFrameSizeH = KHwDisplayBase + KHoDisplayDisplayFrameSizeH; + //df_ds_h0[10:0] - Sets the horizontal size to be displayed in pixel units. + // The valid setting range is 1 to 1,280 at 0 to 1,279 + +const TUint KHoDisplayDisplayFrameSizeV = 0x170; //!!! +const TUint KHwDisplayDisplayFrameSizeV = KHwDisplayBase + KHoDisplayDisplayFrameSizeV; + //df_ds_v0[10:0] - Sets the vertical size to be displayed in line units. The valid setting range is 1-800 at 0-799. + // Caution Ignored depending on the setting of mf_ms_v (memory frame, magnification select, V0, V2,V4) + +const TUint KHoDisplayDisplayFrameExpansionRateH = 0x180; +const TUint KHwDisplayDisplayFrameExpansionRateH = KHwDisplayBase + KHoDisplayDisplayFrameExpansionRateH; + // df_rc_h0[12:0] - set to 0 + +const TUint KHoDisplayDisplayFrameExpansionRateV = 0x190; +const TUint KHwDisplayDisplayFrameExpansionRateV = KHwDisplayBase + KHoDisplayDisplayFrameExpansionRateV; + // df_rc_v0[12:0] - set to 0 + +const TUint KHoDisplayDisplayFramePixelTransmittance = 0x1a0; +const TUint KHwDisplayDisplayPixelTransmittance = KHwDisplayBase + KHoDisplayDisplayFramePixelTransmittance; +const TUint KHoDisplayDisplayFrameTranCtrlLayerTransmittance = 0x1b0; +const TUint KHwDisplayDisplayTranCtrlLayerTransmittance = KHwDisplayBase + KHoDisplayDisplayFrameTranCtrlLayerTransmittance; + //Display frames 0 to 6 transmission control layer transmittance + +const TUint KHoDisplayDisplayFrameColourKeyControl = 0x1c0; +const TUint KHwDisplayDisplayColourKeyControl = KHwDisplayBase + KHoDisplayDisplayFrameColourKeyControl; + // Display frames color key control and color key R, G, B format instruction + +const TUint KHoDisplayDisplayFrameColourKey = 0x1c8; +const TUint KHwDisplayDisplayColourKey = KHwDisplayBase + KHoDisplayDisplayFrameColourKey; + +const TUint KHoDisplayDisplayFrameColourKeyControlRange = 0x1e8; +const TUint KHwDisplayDisplayColourKeyControlRange = KHwDisplayBase + KHoDisplayDisplayFrameColourKeyControlRange; + // Display frame color key control R, G, B permissible range + +const TUint KHoDisplayDisplayFrameConstantColour = 0x1f8; //!!! +const TUint KHwDisplayDisplayFrameConstantColour = KHwDisplayBase + KHoDisplayDisplayFrameConstantColour; + //Sets the constant colours rgb + +const TUint KHoDisplayDisplayFrameBackgroundColour = 0x218; //!!! +const TUint KHwDisplayDisplayFrameBackgroundColour = KHwDisplayBase + KHoDisplayDisplayFrameBackgroundColour; + // df_bc_r[23:16], df_bc_g[15:8] & df_bc_b[7:0] + + +// 220 CDE + +// ------------------------------ +// (5) H/W cursor control register +// ------------------------------ + +// ... + +// ------------------------------ +// (6) V blank update control register +// ------------------------------ + + +// If the display supports Contrast and/or Brightness control then supply the following defines: +// This is only example code... you may need to modify it for your hardware +const TInt KConfigInitialDisplayContrast = 128; +const TInt KConfigLcdMinDisplayContrast = 1; +const TInt KConfigLcdMaxDisplayContrast = 255; +const TInt KConfigInitialDisplayBrightness = 128; +const TInt KConfigLcdMinDisplayBrightness = 1; +const TInt KConfigLcdMaxDisplayBrightness = 255; + +#endif //__NAVIENGINE_LCD_H__ diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/naviengine_pci.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/naviengine_pci.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,150 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\naviengine_pci.h +* +*/ + + + +#ifndef __NAVIENGINE_PCI_H__ +#define __NAVIENGINE_PCI_H__ +//---------------------------------------------------------------------------- +//PCI Definitions +//---------------------------------------------------------------------------- + +//Register Offsets +const TUint KHoPciVid = 0x0; //Vendor Id +const TUint KHoPciDid = 0x2; //Device Id +const TUint KHoPciCmd = 0x04; //PCI Command Register +const TUint KHoPciStatus = 0x06; //PCI Status + +const TInt KNeBridgeNumberOfBars =12; +const TUint KHoBar[KNeBridgeNumberOfBars] = //Defines base address of a window to access AHB space from PCI space + { + 0x10, //0 + 0x14, //1 + 0x18, //2 + 0x40, //3 + 0x48, //4 + 0x50, //5 + 0x58, //6 + 0x60, //7 + 0x68, //8 + 0x80, //9 + 0x90, //10 + 0x98 //11 + }; +//Each ACR controls size and address conversion for its associated BAR +const TUint KHoAcr[KNeBridgeNumberOfBars] = + { + 0xA0, //0 + 0xA4, //1 + 0xA8, //2 + 0x44, //3 + 0x4C, //4 + 0x54, //5 + 0x5C, //6 + 0x64, //7 + 0x6C, //8 + 0x84, //9 + 0x94, //10 + 0x9C //11 + }; + +const TUint KHoError1 = 0xC0; //Error Register 1 +const TUint KHoPciCtrlH = 0xE4; //PCI Control Register Hi +const TUint KHoBarEnable = 0xEC; // PCIBAREn +const TUint KHoCnfig_addr = 0xF8; //PCI Config Address +const TUint KHoCnfig_data = 0xFC; //PCI Config Data + +//Bit masks + +//KPcicmd +const TUint16 KHtPcicmd_Memen = KBit1; //Specifies whether the PCI interface is to acknowkedge a memory access as a PCI target. +const TUint16 KHtPcicmd_Bmasen = KBit2; //Specifies whether the PCI interface is to operate as the PCI master. +const TUint16 KHtPcicmd_Peren = KBit6; // Controls the operation of the device in case of a parity error. 1:React, 0:Ignore +const TUint16 KHtPcicmd_Seren = KBit8; // Controls the operation of the device in case of a system error. 1:React, 0:Ignore + +//KPciStatus +const TUint16 KHtPciStatus_ParityError = KBit15; +const TUint16 KHtPciStatus_SystemError = KBit14; +const TUint16 KHtPciStatus_MasterAbrtRcvd = KBit13; +const TUint16 KHtPciStatus_TargetAbrtRcvd = KBit12; +const TUint16 KHtPciStatus_STA = KBit11; +const TUint16 KHmPciStatus_DevSe = KBit10|KBit9; +const TUint16 KHtPciStatus_DPErrorAsserted = KBit8; +const TUint16 KHtPciStatus_FBBC = KBit7; +const TUint16 KHtPciStatus_UDF = KBit6; + + +//KAcr(N) +const TUint32 KHmAcr_BarMask = KBit8|KBit7|KBit6|KBit5|KBit4; +const TUint32 KHtAcr_P2Ace = KBit0; //Decides whether or not PCI address should be translated before AHB access. + +//KError1 +const TUint32 KHtError1_PEEn = KBit10; // If system error occurs on PCI bus report on the AHB64PCI_ERR pin +const TUint32 KHtError1_AMEn = KBit9; //Assert AHB64PCI_ERR if AHB master receives error response. +const TUint32 KHtError1_SystemError = KBit6; //System error has occurred +const TUint32 KHtError1_AMEr = KBit5; //AHB Master has recieved error response + +//KPciCtrlH +const TUint32 KHtPciCtrlH_CnfigDone = KBit28; +const TUint32 KHtPciCtrlH_Aper = KBit21; // Asserts if an address parity error is detected. +const TUint32 KHtPciCtrlH_Dtep = KBit20; // Asserts if the time of the discard timer is out +const TUint32 KHtPciCtrlH_Dper = KBit19; // Asserts if a data parity error occurs +const TUint32 KHtPciCtrlH_Rlex = KBit18; // Asserts if the retry limit is exceed +const TUint32 KHtPciCtrlH_Mabo = KBit17; // Asserts if the PCI interface generates a master abort signal as the PCI master +const TUint32 KHtPciCtrlH_Tabo = KBit16; // Asserts if the PCI interface detects a target abort signal as the PCI master +const TUint32 KHtPciCtrlH_Aerse = KBit13; +const TUint32 KHtPciCtrlH_Dtimse = KBit12; +const TUint32 KHtPciCtrlH_Perse = KBit11; +const TUint32 KHtPciCtrlH_Rtyse = KBit10; +const TUint32 KHtPciCtrlH_Mase = KBit9; +const TUint32 KHtPciCtrlH_Tase = KBit8; + +namespace Initiator + { + const TUint KHoReg1 = 0xF0; // Pci Initiator 1 - configure how to map AHB-->PCI + const TUint KHoReg2 = 0xF4; // Pci Initiator 2 - configure how to map AHB-->PCI + + //! The upper bits of inbound AHB address are converted to this value + const TUint32 KHmA2PCA = 0xFFFFFC00; + const TUint32 KHmA2PCAMask = 0x1F0; + const TUint32 KHmType = 0xE; + const TUint32 KHtConvEnable = KBit0; + + const TUint32 KHsA2PCA = 9; + const TUint32 KHsA2PCAMask = 4; + const TUint32 KHsType = 1; + const TUint32 KHsConvEnable = 0; + } + +namespace ConfigAddress + { + const TUint32 KHtCnfigEnable = KBit31; // Must be set for bridge to allow access to KHoCnfig_data register. + + const TUint32 KHmBus = 0xFF0000; // Bits 23:16 + const TUint32 KHmDevice = 0xF800; // Bits 15:11 + const TUint32 KHmFunction = 0x700; // Bits 10:8 + const TUint32 KHmOffset = 0xFC; // Bits 7:2 + + const TUint32 KHsBus = 16; + const TUint32 KHsDevice = 11; + const TUint32 KHsFunction = 8; + const TUint32 KHsOffset = 2; + } + +const TUint32 KHwUSBHInternalPciWindowSize = 0x2000; // Size of the system to PCI window at KHwUSBHPhys +#endif // __NAVIENGINE_PCI_H__ diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/naviengine_priv.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/naviengine_priv.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,304 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\naviengine_priv.h +* NE1_TBVariant ASSP architecture private header file +* +*/ + + + +#ifndef __NAVIENGINE_PRIV_H__ +#define __NAVIENGINE_PRIV_H__ +#include +#include +#include +#include + + +//---------------------------------------------------------------------------- +// NaviEngine class +//---------------------------------------------------------------------------- +class TNaviEngine + { + /** + * Accessor functions to hardware resources managed by ASSP (ASIC). Auxiliary and information functions which + * are commonly used by Device Drivers or ASSP/Variant code. + * Some examples below. These examples assume that the hardware blocks they access (e.g. Interrupt controller + * RTC, Clock Control Module, UART, etc) are part of the ASSP. + */ +public: + /** + * Phase 1 initialisation + */ + static void Init1(); + /** + * Phase 3 initialisation + */ + static void Init3(); + /** + * Active waiting loop (not to be used after System Tick timer has been set up - Init3() + * @param aDuration A wait time in milliseconds + */ + IMPORT_C static void BootWaitMilliSeconds(TInt aDuration); + /** + * Read and return the Startup reason of the Hardware + * @return A TMachineStartupType enumerated value + */ + IMPORT_C static TMachineStartupType StartupReason(); + /** + * Read and return the the CPU ID + * @return An integer containing the CPU ID string read off the hardware + */ + IMPORT_C static TInt CpuVersionId(); + /** + * Read Linear base address of debug UART (as selected in obey file or with eshell debugport command). + * @return An integer containing the Linear address of debug Serial Port + */ + IMPORT_C static TUint DebugPortAddr(); + /** + * Read CPU clock period in picoseconds + * @return An integer containing the CPU clock period in picoseconds + */ + IMPORT_C static TUint ProcessorPeriodInPs(); + /** + * Read the current time of the RTC + * @return A value that is the real time as given by a RTC + */ + IMPORT_C static TUint RtcData(); + /** + * Set the RTC time + * @param aValue The real time to set the RTC + */ + IMPORT_C static void SetRtcData(TUint aValue); + /** + * Obtain the physical start address of Video Buffer + * @return the physical start address of Video Buffer + */ + IMPORT_C static TPhysAddr VideoRamPhys(); + static void InitDebugOutput(); + static void DoDebugOutput(TUint aLetter); + +private: + /** Assp-specific implementation for Kern::NanoWait function */ + static void NanoWait(TUint32 aInterval); + }; + +/** All ASSP interrupt souces. */ +enum TNaviEngineAsspInterruptId + { + // The list of core interrupts. + KIntIdDigitiser, // Not a valid value. ///< Internal, clients get value from HCR + KIntIdSound, // Not a valid value. ///< Internal, clients get value from HCR + KIntIdTimer1, // Not a valid value. (Used in template media driver) ///< Internal, clients get value from HCR + KIntIdExpansion, // Not a valid value. (Second level interrupt controller) ///< Internal, clients get value from HCR + EAsspIntIdUsb=11, // Not a valid value. ///< Internal, clients get value from HCR + + KIntCsi0 = 34, ///< Internal, clients get value from HCR + KIntCsi1 = 35, ///< Internal, clients get value from HCR + + KIntIdOstMatchMsTimer = 36, // SoC Timer0 interrupt ///< Internal, clients get value from HCR + KIntId1stMatchMsTimer = 37, // SoC Timer1 interrupt ///< Internal, clients get value from HCR + KIntId2stMatchMsTimer = 38, // SoC Timer2 interrupt ///< Internal, clients get value from HCR + KIntId3stMatchMsTimer = 39, // SoC Timer3 interrupt ///< Internal, clients get value from HCR + KIntId4stMatchMsTimer = 41, // SoC Timer4 interrupt ///< Internal, clients get value from HCR + KIntId5stMatchMsTimer = 42, // SoC Timer5 interrupt ///< Internal, clients get value from HCR + + EIntSd0 = 43, // SD #0 : OXMNIRQ ///< Internal, clients get value from HCR + EIntSd1 = 44, // SD #1 : OXASIOIRQ //SDIO ///< Internal, clients get value from HCR + + EIntNandCtrl = 46, // Nand Controller ///< Internal, clients get value from HCR + + EIntDisp0 = 50, // DISP 0 ///< Internal, clients get value from HCR + + KIntI2S0 = 56, // I2S 0 Interrupts ///< Internal, clients get value from HCR + + EIntPciInt = 65, // PCI Int ///< Internal, clients get value from HCR + EIntPciSErrB = 66, // PCI Systerm Error ///< Internal, clients get value from HCR + EIntPciPErrB = 67, // PCI Parity Error ///< Internal, clients get value from HCR + EIntUsbHIntA = 71, // USB Host Int A ///< Internal, clients get value from HCR + EIntUsbHIntB = 72, // USB Host Int B ///< Internal, clients get value from HCR + EIntUsbHSmi = 73, // USB Host System Management Interrupt ///< Internal, clients get value from HCR + EIntUsbHPme = 74, // USB Host Power Management Event ///< Internal, clients get value from HCR + KIntDMAC32_0_End = 76, ///< Internal, clients get value from HCR + KIntDMAC32_0_Err = 77, ///< Internal, clients get value from HCR + KIntDMAC32_1_End = 78, ///< Internal, clients get value from HCR + KIntDMAC32_1_Err = 79, ///< Internal, clients get value from HCR + KIntDMAC32_2_End = 80, ///< Internal, clients get value from HCR + KIntDMAC32_2_Err = 81, ///< Internal, clients get value from HCR + KIntDMAC32_3_End = 82, ///< Internal, clients get value from HCR + KIntDMAC32_3_Err = 83, ///< Internal, clients get value from HCR + KIntDMAC32_4_End = 84, ///< Internal, clients get value from HCR + KIntDMAC32_4_Err = 85, ///< Internal, clients get value from HCR + + KIntIdUart0 = 86, // SoC Uart #0 ///< Internal, clients get value from HCR + KIntIdUart1 = 87, // SoC Uart #1 ///< Internal, clients get value from HCR + KIntIdUart2 = 88, // SoC Uart #2 ///< Internal, clients get value from HCR + + KIntIdGpio = 94, // gpio ///< Internal, clients get value from HCR + KIntDMAC64_End = 97, ///< Internal, clients get value from HCR + KIntDMAC64_Err = 98, ///< Internal, clients get value from HCR + + KIntCpuProfilingDefaultInterruptBase = 99, //Interrupt used by sampling profilers. + //Each CPU_i is interrupted by interrupt number ECpuProfilingInterrupt + i. + //Therefore we need 1 interrupt per CPU, 99, 100, 101, 102. + + KIntDMAExBus_End = 124, ///< Internal, clients get value from HCR + KIntDMAExBus_Err = 125, ///< Internal, clients get value from HCR + + KNumNaviEngineInts = 128, // Must be >= then the highest interrupt number in use + KNumNaviEngineMaxInts = 256 // The number of interrupt sources in processors. + }; + + +class NaviEngineInterrupt : public Interrupt + { +public: + /** + * These functions are required to initialise the Interrupt controller,or perform housekeeping + * functions, or dispatch the incoming IRQ or FIQ interrupts. + */ + + /** + * initialisation + */ + static void Init1(); + static void Init3(); + + /** + * Housekeeping (disable and clear all hardware interrupt sources) + */ + static void DisableAndClearAll(); + +#ifdef __SMP__ + /** + * IRQ/FIQ dispatchers + */ + static TUint32 IrqDispatch(TUint32 aVector); + static void FiqDispatch(); +#endif +#ifndef __SMP__ + /** + * IRQ/FIQ dispatchers + */ + static void IrqDispatch(); + static void FiqDispatch(); + /** + * Empty interrupt handler + */ + static void Spurious(TAny* anId); + + static SInterruptHandler Handlers[KNumNaviEngineInts]; +#endif + }; + +class NaviEngineAssp : public Asic + { +public: + IMPORT_C NaviEngineAssp(); + +public: + /** + * These are the mandatory Asic class functions which are implemented here rather than in the Variant. + * It makes sense having an ASSP class when there is functionality at Variant/Core level which is common + * to a group of devices and is provided by an IP block(s) which is likely to be used in future generations + * of the same family of devices. + * In general the common functionality includes first-level Interrupt controllers, Power and Reset controllers, + * and timing functions + */ + + /** + * initialisation + */ + IMPORT_C virtual void Init1(); + IMPORT_C virtual void Init3(); + /** + * Read and return the Startup reason of the Super Page (set up by Bootstrap) + * @return A TMachineStartupType enumerated value + * @see TMachineStartupType + */ + IMPORT_C virtual TMachineStartupType StartupReason(); + + /** + * timing functions + */ + + /** + * Obtain the period of System Tick timer in microseconds + * @return Period of System Tick timer in microseconds + */ + IMPORT_C virtual TInt MsTickPeriod(); + /** + * Obtain System Time from the RTC + * @return System Time in seconds from 00:00 hours of 1/1/2000 + */ + IMPORT_C virtual TInt SystemTimeInSecondsFrom2000(TInt& aTime); + /** + * Obtain Adjust the RTC with new System Time (from 00:00 hours of 1/1/2000) + * @return System wide error code + */ + IMPORT_C virtual TInt SetSystemTimeInSecondsFrom2000(TInt aTime); + /** + * Obtain the time it takes to execute two processor instructions + * @return Time in nanoseconds it takes two execute 2 instructions at the processor clock speed + */ + IMPORT_C virtual TUint32 NanoWaitCalibration(); + /** + * @param aChar Character to be output by debug serial port + */ + IMPORT_C virtual void DebugOutput(TUint aChar); + +public: + /** + * for derivation by Variant + */ + + /** + * external interrupt handling + * used by second-level interrupt controllers at Variant level + */ + virtual TInt InterruptBind(TInt anId, TIsr anIsr, TAny* aPtr)=0; + virtual TInt InterruptUnbind(TInt anId)=0; + virtual TInt InterruptEnable(TInt anId)=0; + virtual TInt InterruptDisable(TInt anId)=0; + virtual TInt InterruptClear(TInt anId)=0; + + /** + * USB client controller - Some example functions for the case that USB cable detection and + * UDC connect/disconnect functionality are part of the Variant. + * Pure virtual functions called by the USB PSL, to be implemented by the Variant (derived class). + * If this functionality is part of the ASSP then these functions can be removed and calls to them + * in the PSL (./pa_usbc.cpp) replaced by the appropriate internal operations. + */ + virtual TBool UsbClientConnectorDetectable()=0; + virtual TBool UsbClientConnectorInserted()=0; + virtual TInt RegisterUsbClientConnectorCallback(TInt (*aCallback)(TAny*), TAny* aPtr)=0; + virtual void UnregisterUsbClientConnectorCallback()=0; + virtual TBool UsbSoftwareConnectable()=0; + virtual TInt UsbConnect()=0; + virtual TInt UsbDisconnect()=0; + + /** + * miscellaneous + */ + virtual TInt VideoRamSize()=0; + +public: + static NaviEngineAssp* Variant; + static TPhysAddr VideoRamPhys; + NTimerQ* iTimerQ; + TBool iDebugInitialised; + }; + +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/navienginecia.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/navienginecia.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\navienginecia.h +* +*/ + + + +#ifndef __NAVIENGINECIA_H__ +#define __NAVIENGINECIA_H__ + +// CIA symbols for ASSP code? +#if defined(__GCC32__) +// CIA symbol macros for Gcc98r2 +#define CSM_ZN7NTimerQ4TickEv " Tick__7NTimerQ" +#elif defined(__ARMCC__) +// CIA symbol macros for RVCT +#define CSM_ZN7NTimerQ4TickEv " __cpp(NTimerQ::Tick)" +#else +// CIA symbol macros for EABI assemblers +#define CSM_ZN7NTimerQ4TickEv " _ZN7NTimerQ4TickEv" +#endif + + +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/navienginedma.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/navienginedma.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,366 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\navienginedma.h +* Definitions and constants of NE SoC DMA Controller. +* See 2.10 DMA Controllers in NaviEngine User Manual +* +*/ + + +#ifndef __NAVIENGINEDMA_H__ +#define __NAVIENGINEDMA_H__ + +#include +#include + +#include + + +#define FUNC_LOG __KTRACE_OPT(KDMA, Kern::Printf(__PRETTY_FUNCTION__)) +#define PRINT(S) __KTRACE_OPT(KDMA, Kern::Printf("%s = 0x%08x", #S, (S))) + +/* + * The list of DMA logical channels. + * Use these values to populate iCookie when openning DMA channel. + */ +enum ENaviengineDmaChannels + { + EDMAChannelSD0, ///< Internal, clients get value from HCR + EDMAChannelSD1, ///< Internal, clients get value from HCR + + EDMAChannelI2S0RX, ///< Internal, clients get value from HCR + EDMAChannelI2S0TX, ///< Internal, clients get value from HCR + EDMAChannelI2S1RX, ///< Internal, clients get value from HCR + EDMAChannelI2S1TX, ///< Internal, clients get value from HCR + EDMAChannelI2S2RX, ///< Internal, clients get value from HCR + EDMAChannelI2S2TX, ///< Internal, clients get value from HCR + EDMAChannelI2S3RX, ///< Internal, clients get value from HCR + EDMAChannelI2S3TX, ///< Internal, clients get value from HCR + + EDMAChannelUART0RX, ///< Internal, clients get value from HCR + EDMAChannelUART0TX, ///< Internal, clients get value from HCR + EDMAChannelUART1RX, ///< Internal, clients get value from HCR + EDMAChannelUART1TX, ///< Internal, clients get value from HCR + EDMAChannelUART2RX, ///< Internal, clients get value from HCR + EDMAChannelUART2TX, ///< Internal, clients get value from HCR + + EDmaMemToMem0, ///< Internal, clients get value from HCR + EDmaMemToMem1, ///< Internal, clients get value from HCR + EDmaMemToMem2, ///< Internal, clients get value from HCR + EDmaMemToMem3, ///< Internal, clients get value from HCR + + EDma32ChannelCount, //End of DMA32 channels + + //Enum indexes into KDMAChannelLocator array - it doesn't have a gap + EDma64MemToMem0 = EDma32ChannelCount, + EDma64MemToMem1, + EDma64MemToMem2, + EDma64MemToMem3, + + EDmaChannelCount, // End of DMA64 channels + }; + +/* + * The list of DMA controllers in NE SoC + */ +enum ENaviEngineDmaController + { + EDmaCtrlExBus, // not supported - there is no any H/W of interest + EDMACtrl32, // DMAC32(8C) + EDmaCtrl64 // DMAC64(4C) - DMA controller on 64 Bit AXI bus + }; + +/* + * Specifies H/W parameters of logical DMA channels (@see ENaviengineDmaChannels). + */ +struct TDMAChannelLocator + { + ENaviEngineDmaController iDMACtrl; + TInt iGroup; // 0 for EDmaCtrlExBus & 0-4 EDMACtrl32 + TInt iSubChannel; // 0-3 for EDmaCtrlExBus & 0-7 for each group of EDMACtrl32 + TInt iDMACHCReg; // The content CHC register (excluding subchannel) + TInt iTransferShiftSize;//0-Byte, 1-HalfWord, 2-Word, 4-FourWords, 5-EightWords, 6-SixteenWords + }; + +const TInt KDmaHWCtrl32Count = 5; // The number of DMA32 controllers +const TInt KDmaCtrl32HWSubChannelCount = 8; // The number of subchannels per controller. + +const TUint KDMAGroupOffset = 0x1000; // Regitsers' offset per cotroller +const TUint KDMAChannelOffset = 0x20; // Registers' offset per subchannel + +/****** Offsets and bitmasks of DMA32 registers ************/ +const TUint KHoDMASAB = 0x00; // Source Address Base +const TUint KHoDMADAB = 0x04; // Destination Address Base +const TUint KHoDMATCB = 0x08; // Transfer Count Base +const TUint KHoDMASAW = 0x0c; // Source Address Work +const TUint KHoDMADAW = 0x10; // Destination Address Work +const TUint KHoDMATCW = 0x14; // Transfer Count Work +const TUint KHoDMACHC = 0x18; // Channel Control Register +const TUint KHmDMACHC_SEL = 7; // Channel selection mask +const TUint KHvDMACHC_SW = 0xd1226000; // Settings for SW transfer. Word alignement for both source & dest. +const TUint KHvDMACHC_SDR = 0xd0292600; // Settings for SD0 Read channel +const TUint KHvDMACHC_SDW = 0xd0922610; // Settings for SD1 Write channel + +const TUint KHsDMACHC_HP = 28; // Sets the values output to HPROT[3:0] during DMA transfer. 1101 initial value +const TUint KHvDMACHC_HP = 0xd; // initial value for KHsDMACHC_HP bits +const TUint KHtDMACHC_TM = (1<<24); // transfer mode- 0:single transfer, 1:block transfer (memory-to-memory transfers only!) +const TUint KHtDMACHC_DAD = (1<<23); // destination address count direction- 0:increment, 1:fixed +const TUint KHtDMACHC_SAD = (1<<19); // source address count direction- 0:increment, 1:fixed +const TUint KHsDMACHC_DDS = 20; // transfer data size at the DMA transfer destination. +const TUint KHsDMACHC_SDS = 16; // transfer data size at the DMA transfer source. +/* 000: Byte (8 bits) (initial value) + 001: Half-word (16 bits) + 010: Word (32 bits) + 100: 4 words (128 bits) + 101: 8 words (256 bits) + 110: 16 words (512 bits) + Others: Setting prohibited */ +const TUint KHtDMACHC_TCM = (1<<14); // Masks output to DMATCO[n]: 0: not mask the output, 1:mast the output + +const TUint KHsDMACHC_AM = 12; // Sets the DMAACK[n] output timing, 00: Pulse mode (active for one clock), + // 01: Level mode (active as long as the selected DMAREQ inputs remain) 1x: Masks DMAACK[n]. +const TUint KHtDMACHC_LVL = (1<<10); // DMA request is detected 1: at the level or 0: edge of the signal. +const TUint KHtDMACHC_HIEN = (1<<9); // 1: high level or rising edge of signal, 0: does not recognize +const TUint KHtDMACHC_LOEN = (1<<8); // 1: low level or falling edge of signal, 0: does not recognize +const TUint KHtDMACHC_REQD = (1<<4); // Selects whether DMAREQ SEL bit is on the source or destination side. + /* Also selects the timing at which DMAACK becomes active. + 0: Source side. DMAACK becomes active upon read (initial value). + 1: Destination side. DMAACK becomes active upon write.*/ +const TUint KHsDMACHC_SEL = 0; // Selects one of eight DMAREQ/DMAACK/DMATCO signals. + +// Settings for I2S TX channels +const TUint KHvDMACHC_I2SW = + KHvDMACHC_HP << KHsDMACHC_HP | // use initial value for KHsDMACHC_HP bits + KHtDMACHC_DAD | // destination address fixed, increment source only + 1 << KHsDMACHC_DDS | // transfer data size at the DMA transfer destination. + 1 << KHsDMACHC_SDS | // transfer data size at the DMA transfer source. + 0 << KHsDMACHC_AM | // 00: Pulse mode (active for one clock),01: Level mode (active as long as the selected DMAREQ inputs remain) 1x: Masks DMAACK[n]. + KHtDMACHC_LVL | // DMA request is detected 1: at the level or 0: edge of the signal. + KHtDMACHC_HIEN| // 1: high level or rising edge of signal, 0: does not recognize + 0 << KHsDMACHC_SEL; + + +// Settings for I2S RX channels +const TUint KHvDMACHC_I2SR = + KHvDMACHC_HP << KHsDMACHC_HP | // use initial value for KHsDMACHC_HP bits + KHtDMACHC_SAD | // source address fixed, increment destination only + 1 << KHsDMACHC_DDS | // transfer data size at the DMA transfer destination. + 1 << KHsDMACHC_SDS | // transfer data size at the DMA transfer source. + 0 << KHsDMACHC_AM | // 00: Pulse mode (active for one clock),01: Level mode (active as long as the selected DMAREQ inputs remain) 1x: Masks DMAACK[n]. + KHtDMACHC_LVL | // DMA request is detected 1: at the level or 0: edge of the signal. + KHtDMACHC_HIEN| // 1: high level or rising edge of signal, 0: does not recognize + 0 << KHsDMACHC_SEL; + + +const TUint KHoDMACHS = 0x1c; // Channel Status Register +const TUint KHtDMACHS_EN = 0x001;// Enables/disables DMA transfer. +const TUint KHtDMACHS_EN_EN = 0x002;// Enables writing to EN bit. +const TUint KHtDMACHS_STG = 0x004;// SW activation of DMA transfer. +const TUint KHtDMACHS_FCLR = 0x008;// Clears TC, END, ERR & RQST bits. +const TUint KHtDMACHS_RQST = 0x010;// Indicates that transfer request has been received - RO. +const TUint KHtDMACHS_ACT = 0x020;// Indicates that DMAC is performing transfer - RO. +const TUint KHtDMACHS_ERR = 0x040;// Error in transfer - RO. +const TUint KHtDMACHS_END = 0x080;// DMA transfer from working set is completed. +const TUint KHtDMACHS_TC = 0x100;// DMA transfer from working set is completed while BVALID is 0. +const TUint KHtDMACHS_BVALID = 0x200;// Indicates valid values in base set. +const TUint KHoDMACONT = 0x300; // Control Register +const TUint KHvDMACONT_INIT_VALUE = 0; +const TUint KHoDMASTAT = 0x304; // Status Register +const TUint KHmDSTAT_TC_DMA32 = 0xff000000; +const TUint KHsDSTAT_TC = 24; +const TUint KHsDSTAT_END = 20; +const TUint KHsDSTAT_ER = 16; +const TUint KHmDSTAT_DMA32 = 0x01000001; + + +static const TUint KMaxDMAUnitTransferLen = 0x10000;// max DMA transfer length in units. + +/** +Constants for the 64 bit AXI DMA controller +*/ +namespace Dma64 +{ + const TInt KChannelCount = 4; // The number of channels on the controller. + + /** + Hardware definitions used for DMA channels + */ + namespace Channel + { + /** + Register set offsets + */ + namespace RegSet + { + enum TRegSets {ENext0, ENext1, ECurrent, ERegSetCount}; + const TUint32 KHoBases[ERegSetCount] = {0x0, 0xc, 0x18}; + const TUint32 KHoSrcAddr = 0x0; + const TUint32 KHoDstAddr = 0x4; + const TUint32 KHoTranByte = 0x8; // Transaction byte register + }; + + /** + Base offsets for each channel + */ + const TUint32 KHoBases[KChannelCount] = { 0x0, 0x40, 0x80, 0xC0 }; + + /** + Offset and bit definitions for channel status register + */ + namespace Status + { + const TUint32 KHoBase = 0x24; + + const TUint32 KHtDescErr = KBit10; + const TUint32 KHtDescWb = KBit9; + const TUint32 KHtDescLoad = KBit8; + const TUint32 KHtTc = KBit6; + const TUint32 KHtEnd = KBit5; + const TUint32 KHtSuspended = KBit3; + const TUint32 KHtAct = KBit2; + const TUint32 KHtRqst = KBit1; + const TUint32 KHtEnabled = KBit0; + } + + /** + Offset and bit definitions for channel control register + */ + namespace Ctrl + { + const TUint32 KHoBase = 0x28; + + const TUint32 KHtSetEnable = KBit0; + const TUint32 KHtSwTrigger = KBit2; + const TUint32 KHtSwReset = KBit3; + const TUint32 KHtClrEnd = KBit5; + const TUint32 KHtClrTc = KBit6; //Clear the transfer complete status + const TUint32 KHtSetSuspend = KBit8; + const TUint32 KHtClrSuspend = KBit9; + }; + + /** + Offset and bit definitions for channel configuration register + */ + namespace Cfg + { + const TUint32 KHoBase = 0x2c; + + const TUint32 KHtLinkMode = KBit31; + const TUint32 KHtCompMask = KBit25; + const TUint32 KHtEndMask = KBit24; + const TUint32 KHtTransMode = KBit22; + + const TUint32 KHsDestDataSize = 16; + const TUint32 KHsSrcDataSize = 12; + + const TUint32 KHmDestDataSize = (0xF << KHsDestDataSize); + const TUint32 KHmSrcDataSize = (0xF << KHsSrcDataSize); + }; + + /** + Offset and bit definitions for channel interval register + */ + namespace Interval + { + const TUint32 KHo = 0x30; + + const TUint32 KHm = 0x0000FFFF; + }; + + const TUint32 KHoExt = 0x34; + + const TUint32 KHoNxtLnkAddr = 0x38; + const TUint32 KHoCurrtLnkAddr = 0x3c; + }; + + /** + Registers common to all channels + */ + namespace Cmn + { + const TUint32 KHoCtrl = 0x300; + const TUint32 KHoEn = 0x310; + const TUint32 KHoErr = 0x314; + const TUint32 KHoEnd = 0x318; + const TUint32 KHoTc = 0x31C; + const TUint32 KHoSus = 0x320; + }; + + const TUint KDma64MaxTransferBytes = KMaxTUint32; + +/** + Layout of the 64 bit DMAC's transfer descriptor +*/ + struct TDma64Desc + { + TDma64Desc() {Clear();} + void Clear() {memclr(this, sizeof(*this));} + + enum TTransferSize + { + E512Bit = 0x6, + }; + + void SetSourceDataSize(TTransferSize aTransferSize) + { + iConfig &= ~Channel::Cfg::KHmSrcDataSize; + iConfig |= (aTransferSize << Channel::Cfg::KHsSrcDataSize); + } + + void SetDestDataSize(TTransferSize aTransferSize) + { + iConfig &= ~Channel::Cfg::KHmDestDataSize; + iConfig |= (aTransferSize << Channel::Cfg::KHsDestDataSize); + } + +#ifdef _DEBUG + void Print() + { + FUNC_LOG; + PRINT(iHeader); + PRINT(iSrcAddr); + PRINT(iDestAddr); + PRINT(iTransactionByte); + PRINT(iConfig); + PRINT(iInterval); + PRINT(iExtension); + PRINT(iNextLink); + + PRINT(Epoc::LinearToPhysical((TUint32)this)); + } +#endif + + TUint32 iHeader; + TUint32 iSrcAddr; + TUint32 iDestAddr; + TUint32 iTransactionByte; + TUint32 iConfig; + TUint32 iInterval; + TUint32 iExtension; + TUint32 iNextLink; + }; + + /** Bit defs for hardware descriptor header */ + namespace HwDesHeader + { + const TUint32 KHtDim = KBit3; // Descriptor header load interrupt mask: 1: do not issue irq; 0: issue irq. + const TUint32 KHtWbd = KBit2; // Write back disable. Set to 1 to disable writeback + const TUint32 KHtLe = KBit1; // 1: This is the final link + const TUint32 KHtLv = KBit0; // 1: This link is valid + }; + +}; + +#endif // #ifndef __NAVIENGINEDMA_H__ diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/pa_usbc.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/pa_usbc.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,2004 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\pa_usbc.cpp +* Platform-dependent USB client controller layer (USB PSL). +* +*/ + + + + +#include // /assp/naviengine/ +#include // /assp/naviengine/ + +#include // /drivers/ + +#include "pa_usbc.h" // . + +// Debug support +#ifdef _DEBUG +static const char KUsbPanicCat[] = "USB PSL"; +#endif + + +// Define USB_SUPPORTS_PREMATURE_STATUS_IN to enable proper handling of a premature STATUS_IN stage, i.e. a +// situation where the host sends less data than first announced and instead of more data (OUT) will send an +// IN token to start the status stage. What we do in order to implement this here is to prime the TX fifo with +// a ZLP immediately when we find out that we're dealing with a DATA_OUT request. This way, as soon as the +// premature IN token is received, we complete the transaction by sending off the ZLP. If we don't prime the +// TX fifo then there is no way for us to recognise a premature status because the IN token itself doesn't +// raise an interrupt. We would simply wait forever for more data, or rather we would time out and the host +// would move on and send the next Setup packet. +// The reason why we would not want to implement the proper behaviour is this: After having primed the TX fifo +// with a ZLP, it is impossible for a user to reject such a (class/vendor specific) Setup request, basically +// because the successful status stage happens automatically. At the time the user has received and decoded +// the Setup request there's for her no way to stall Ep0 in order to show to the host that this Setup packet +// is invalid or inappropriate or whatever, because she cannot prevent the status stage from happening. +// (All this is strictly true only if the amount of data in the data stage is less than or equal to Ep0's max +// packet size. However this is almost always the case.) +//#define USB_SUPPORTS_PREMATURE_STATUS_IN + + +static const TUsbcEndpointCaps DeviceEndpoints[KUsbTotalEndpoints] = + { + // Hardware # iEndpoints index + {KEp0MaxPktSzMask, (KUsbEpTypeControl | KUsbEpDirOut)}, // 0 - 0 + {KEp0MaxPktSzMask, (KUsbEpTypeControl | KUsbEpDirIn )}, // 0 - 1 + {KUsbEpNotAvailable, KUsbEpNotAvailable}, // --- Not present + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirIn )}, // 1 - 3 + {KBlkMaxPktSzMask, (KUsbEpTypeBulk | KUsbEpDirOut)}, // 2 - 4 + {KUsbEpNotAvailable, KUsbEpNotAvailable}, // --- Not present + {KUsbEpNotAvailable, KUsbEpNotAvailable}, // --- Not present + {KIsoMaxPktSzMask, (KUsbEpTypeIsochronous | KUsbEpDirIn )}, // 3 - 7 + {KIsoMaxPktSzMask, (KUsbEpTypeIsochronous | KUsbEpDirOut)}, // 4 - 8 + {KUsbEpNotAvailable, KUsbEpNotAvailable}, // --- Not present + {KUsbEpNotAvailable, KUsbEpNotAvailable}, // --- Not present + {KIntMaxPktSzMask, (KUsbEpTypeInterrupt | KUsbEpDirIn )}, // 5 - 11 + }; + + +// --- TEndpoint -------------------------------------------------------------- + +TEndpoint::TEndpoint() +// +// Constructor +// + : iRxBuf(NULL), iReceived(0), iLength(0), iZlpReqd(EFalse), iNoBuffer(EFalse), iDisabled(EFalse), + iPackets(0), iLastError(KErrNone), iRequest(NULL), iRxTimer(RxTimerCallback, this), + iRxTimerSet(EFalse), iRxMoreDataRcvd(EFalse), iPacketIndex(NULL), iPacketSize(NULL) + { + __KTRACE_OPT(KUSB, Kern::Printf("TEndpoint::TEndpoint")); + } + + +void TEndpoint::RxTimerCallback(TAny* aPtr) +// +// (This function is static.) +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TEndpoint::RxTimerCallback")); + + TEndpoint* const ep = static_cast(aPtr); + if (!ep) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: !ep")); + } + else if (!ep->iRxTimerSet) + { + // Timer 'stop' substitute (instead of stopping it, + // we just let it expire after clearing iRxTimerSet) + __KTRACE_OPT(KUSB, Kern::Printf("!ep->iRxTimerSet - returning")); + } + else if (!ep->iRxBuf) + { + // Request already completed + __KTRACE_OPT(KUSB, Kern::Printf("!ep->iRxBuf - returning")); + } + else if (ep->iRxMoreDataRcvd) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > rx timer cb: not yet completing...")); + ep->iRxMoreDataRcvd = EFalse; + ep->iRxTimer.Again(KRxTimerTimeout); + } + else + { + __KTRACE_OPT(KUSB, Kern::Printf(" > rx timer cb: completing now...")); + *ep->iPacketSize = ep->iReceived; + ep->iController->RxComplete(ep); + } + } + + +// --- TNaviEngineAsspUsbcc public --------------------------------------------------- + +TNaviEngineAsspUsbcc::TNaviEngineAsspUsbcc() +// +// Constructor. +// + : iCableConnected(ETrue), iBusIsPowered(EFalse), + iInitialized(EFalse), iUsbClientConnectorCallback(UsbClientConnectorCallback), + iEp0Configured(EFalse) + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::TNaviEngineAsspUsbcc")); + + iAssp = static_cast(Arch::TheAsic()); + + iSoftwareConnectable = iAssp->UsbSoftwareConnectable(); + + iCableDetectable = iAssp->UsbClientConnectorDetectable(); + + if (iCableDetectable) + { + // Register our callback for detecting USB cable insertion/removal. + // We ignore the error code: if the registration fails, we just won't get any events. + // (Which of course is bad enough...) + (void) iAssp->RegisterUsbClientConnectorCallback(iUsbClientConnectorCallback, this); + // Call the callback straight away so we get the proper PIL state from the beginning. + (void) UsbClientConnectorCallback(this); + } + + for (TInt i = 0; i < KUsbTotalEndpoints; i++) + { + iEndpoints[i].iController = this; + } + +#ifdef SEPARATE_USB_DFC_QUEUE + iPowerUpDfc.SetDfcQ(DfcQ(0) ); + iPowerDownDfc.SetDfcQ(DfcQ(0) ); +#endif + } + + +TInt TNaviEngineAsspUsbcc::Construct() +// +// Construct. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::Construct")); + + TUsbcDeviceDescriptor* DeviceDesc = TUsbcDeviceDescriptor::New( + 0x00, // aDeviceClass + 0x00, // aDeviceSubClass + 0x00, // aDeviceProtocol + KEp0MaxPktSz, // aMaxPacketSize0 + KUsbVendorId, // aVendorId + KUsbProductId, // aProductId + KUsbDevRelease, // aDeviceRelease + 1); // aNumConfigurations + if (!DeviceDesc) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for dev desc failed.")); + return KErrGeneral; + } + + TUsbcConfigDescriptor* ConfigDesc = TUsbcConfigDescriptor::New( + 1, // aConfigurationValue + ETrue, // aSelfPowered (see 12.4.2 "Bus-Powered Devices") + ETrue, // aRemoteWakeup + 0); // aMaxPower (mA) + if (!ConfigDesc) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for config desc failed.")); + return KErrGeneral; + } + + TUsbcLangIdDescriptor* StringDescLang = TUsbcLangIdDescriptor::New(KUsbLangId); + if (!StringDescLang) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for lang id $ desc failed.")); + return KErrGeneral; + } + + // ('sizeof(x) - 2' because 'wchar_t KStringXyz' created a wide string that ends in '\0\0'.) + + TUsbcStringDescriptor* StringDescManu = + TUsbcStringDescriptor::New(TPtr8( + const_cast(reinterpret_cast(KStringManufacturer)), + sizeof(KStringManufacturer) - 2, sizeof(KStringManufacturer) - 2)); + if (!StringDescManu) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for manufacturer $ desc failed.")); + return KErrGeneral; + } + + TUsbcStringDescriptor* StringDescProd = + TUsbcStringDescriptor::New(TPtr8( + const_cast(reinterpret_cast(KStringProduct)), + sizeof(KStringProduct) - 2, sizeof(KStringProduct) - 2)); + if (!StringDescProd) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for product $ desc failed.")); + return KErrGeneral; + } + + TUsbcStringDescriptor* StringDescSer = + TUsbcStringDescriptor::New(TPtr8( + const_cast(reinterpret_cast(KStringSerialNo)), + sizeof(KStringSerialNo) - 2, sizeof(KStringSerialNo) - 2)); + if (!StringDescSer) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for serial no $ desc failed.")); + return KErrGeneral; + } + + TUsbcStringDescriptor* StringDescConf = + TUsbcStringDescriptor::New(TPtr8( + const_cast(reinterpret_cast(KStringConfig)), + sizeof(KStringConfig) - 2, sizeof(KStringConfig) - 2)); + if (!StringDescConf) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for config $ desc failed.")); + return KErrGeneral; + } + + const TBool r = InitialiseBaseClass(DeviceDesc, + ConfigDesc, + StringDescLang, + StringDescManu, + StringDescProd, + StringDescSer, + StringDescConf); + if (!r) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: UsbClientController::InitialiseBaseClass failed.")); + return KErrGeneral; + } + + return KErrNone; + } + + +TNaviEngineAsspUsbcc::~TNaviEngineAsspUsbcc() +// +// Destructor. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::~TNaviEngineAsspUsbcc")); + + // Unregister our callback for detecting USB cable insertion/removal + if (iCableDetectable) + { + iAssp->UnregisterUsbClientConnectorCallback(); + } + if (iInitialized) + { + // (The explicit scope operator is used against Lint warning #1506.) + TNaviEngineAsspUsbcc::StopUdc(); + } + } + + +TBool TNaviEngineAsspUsbcc::DeviceStateChangeCaps() const +// +// Returns capability of hardware to accurately track the device state (Chapter 9 state). +// + { + // TO DO: Return EFalse or ETrue here, depending on whether the UDC supports exact device state tracking + // (most don't). + return EFalse; + } + + +TInt TNaviEngineAsspUsbcc::SignalRemoteWakeup() +// +// Forces the UDC into a non-idle state to perform a remote wakeup operation. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::SignalRemoteWakeup")); + + // TO DO: Do here whatever is necessary for the UDC to signal remote wakeup. + + return KErrNone; + } + + +void TNaviEngineAsspUsbcc::DumpRegisters() +// +// Dumps the contents of a number of UDC registers to the screen (using Kern::Printf()). +// Rarely used, but might prove helpful when needed. +// + { + Kern::Printf("TCotullaUsbcc::DumpRegisters:"); + + // TO DO: Print the contents of some (or all) UDC registers here. + } + + +TDfcQue* TNaviEngineAsspUsbcc::DfcQ(TInt /* aUnit */) +// +// Returns a pointer to the kernel DFC queue to be used buy the USB LDD. +// + { + return Kern::DfcQue0(); + } + + +// --- TNaviEngineAsspUsbcc private virtual ------------------------------------------ + +TInt TNaviEngineAsspUsbcc::SetDeviceAddress(TInt aAddress) +// +// Sets the PIL-provided device address manually (if possible - otherwise do nothing). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::SetDeviceAddress: %d", aAddress)); + + // TO DO (optional): Set device address here. + + if (aAddress) + { + // Address can be zero. + MoveToAddressState(); + } + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::ConfigureEndpoint(TInt aRealEndpoint, const TUsbcEndpointInfo& aEndpointInfo) +// +// Prepares (enables) an endpoint (incl. Ep0) for data transmission or reception. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::ConfigureEndpoint(%d)", aRealEndpoint)); + + const TInt n = ArrayIdx2TemplateEp(aRealEndpoint); + if (n < 0) + return KErrArgument; + + TEndpoint* const ep = &iEndpoints[aRealEndpoint]; + if (ep->iDisabled == EFalse) + { + EnableEndpointInterrupt(n); + } + ep->iNoBuffer = EFalse; + if (n == 0) + iEp0Configured = ETrue; + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::DeConfigureEndpoint(TInt aRealEndpoint) +// +// Disables an endpoint (incl. Ep0). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::DeConfigureEndpoint(%d)", aRealEndpoint)); + + const TInt n = ArrayIdx2TemplateEp(aRealEndpoint); + if (n < 0) + return KErrArgument; + + DisableEndpointInterrupt(n); + if (n == 0) + iEp0Configured = EFalse; + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::AllocateEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource) +// +// Puts the requested endpoint resource to use, if possible. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::AllocateEndpointResource(%d): %d", + aRealEndpoint, aResource)); + + // TO DO: Allocate endpoint resource here. + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::DeAllocateEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource) +// +// Stops the use of the indicated endpoint resource, if beneficial. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::DeAllocateEndpointResource(%d): %d", + aRealEndpoint, aResource)); + + // TO DO: Deallocate endpoint resource here. + + return KErrNone; + } + + +TBool TNaviEngineAsspUsbcc::QueryEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource) const +// +// Returns the status of the indicated resource and endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::QueryEndpointResource(%d): %d", + aRealEndpoint, aResource)); + + // TO DO: Query endpoint resource here. The return value should reflect the actual state. + return ETrue; + } + + +TInt TNaviEngineAsspUsbcc::OpenDmaChannel(TInt aRealEndpoint) +// +// Opens a DMA channel for this endpoint. This function is always called during the creation of an endpoint +// in the PIL. If DMA channels are a scarce resource, it's possible to do nothing here and wait for an +// AllocateEndpointResource call instead. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::OpenDmaChannel(%d)", aRealEndpoint)); + + // TO DO (optional): Open DMA channel here. + + // An error should only be returned in case of an actual DMA problem. + return KErrNone; + } + + +void TNaviEngineAsspUsbcc::CloseDmaChannel(TInt aRealEndpoint) +// +// Closes a DMA channel for this endpoint. This function is always called during the destruction of an +// endpoint in the PIL. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::CloseDmaChannel(%d)", aRealEndpoint)); + + // TO DO (optional): Close DMA channel here (only if it was opened via OpenDmaChannel). + } + + +TInt TNaviEngineAsspUsbcc::SetupEndpointRead(TInt aRealEndpoint, TUsbcRequestCallback& aCallback) +// +// Sets up a read request for an endpoint on behalf of the LDD. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::SetupEndpointRead(%d)", aRealEndpoint)); + + if (!IS_OUT_ENDPOINT(aRealEndpoint)) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: !IS_OUT_ENDPOINT(%d)", aRealEndpoint)); + return KErrArgument; + } + TEndpoint* const ep = &iEndpoints[aRealEndpoint]; + if (ep->iRxBuf != NULL) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > WARNING: iEndpoints[%d].iRxBuf != NULL", aRealEndpoint)); + return KErrGeneral; + } + ep->iRxBuf = aCallback.iBufferStart; + ep->iReceived = 0; + ep->iLength = aCallback.iLength; + // For Bulk reads we start out with the assumption of 1 packet (see BulkReceive for why): + ep->iPackets = IS_BULK_OUT_ENDPOINT(aRealEndpoint) ? 1 : 0; + ep->iRequest = &aCallback; + ep->iPacketIndex = aCallback.iPacketIndex; + if (IS_BULK_OUT_ENDPOINT(aRealEndpoint)) + *ep->iPacketIndex = 0; // a one-off optimization + ep->iPacketSize = aCallback.iPacketSize; + + const TInt n = ArrayIdx2TemplateEp(aRealEndpoint); + if (ep->iDisabled) + { + ep->iDisabled = EFalse; + EnableEndpointInterrupt(n); + } + else if (ep->iNoBuffer) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > There had been no Rx buffer available: reading Rx FIFO now")); + ep->iNoBuffer = EFalse; + if (IS_BULK_OUT_ENDPOINT(aRealEndpoint)) + { + BulkReadRxFifo(n); + } + else if (IS_ISO_OUT_ENDPOINT(aRealEndpoint)) + { + IsoReadRxFifo(n); + } + else + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Endpoint not found")); + } + } + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::SetupEndpointWrite(TInt aRealEndpoint, TUsbcRequestCallback& aCallback) +// +// Sets up a write request for an endpoint on behalf of the LDD. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::SetupEndpointWrite(%d)", aRealEndpoint)); + + if (!IS_IN_ENDPOINT(aRealEndpoint)) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: !IS_IN_ENDPOINT(%d)", aRealEndpoint)); + return KErrArgument; + } + TEndpoint* const ep = &iEndpoints[aRealEndpoint]; + if (ep->iTxBuf != NULL) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: iEndpoints[%d].iTxBuf != NULL", aRealEndpoint)); + return KErrGeneral; + } + ep->iTxBuf = aCallback.iBufferStart; + ep->iTransmitted = 0; + ep->iLength = aCallback.iLength; + ep->iPackets = 0; + ep->iZlpReqd = aCallback.iZlpReqd; + ep->iRequest = &aCallback; + + const TInt n = ArrayIdx2TemplateEp(aRealEndpoint); + if (IS_BULK_IN_ENDPOINT(aRealEndpoint)) + { + if (ep->iDisabled) + { + ep->iDisabled = EFalse; + EnableEndpointInterrupt(n); + } + BulkTransmit(n); + } + else if (IS_ISO_IN_ENDPOINT(aRealEndpoint)) + { + IsoTransmit(n); + } + else if (IS_INT_IN_ENDPOINT(aRealEndpoint)) + { + IntTransmit(n); + } + else + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Endpoint not found")); + } + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::CancelEndpointRead(TInt aRealEndpoint) +// +// Cancels a read request for an endpoint on behalf of the LDD. +// No completion to the PIL occurs. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::CancelEndpointRead(%d)", aRealEndpoint)); + + if (!IS_OUT_ENDPOINT(aRealEndpoint)) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: !IS_OUT_ENDPOINT(%d)", aRealEndpoint)); + return KErrArgument; + } + TEndpoint* const ep = &iEndpoints[aRealEndpoint]; + if (ep->iRxBuf == NULL) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > WARNING: iEndpoints[%d].iRxBuf == NULL", aRealEndpoint)); + return KErrNone; + } + ep->iRxBuf = NULL; + ep->iReceived = 0; + ep->iNoBuffer = EFalse; + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::CancelEndpointWrite(TInt aRealEndpoint) +// +// Cancels a write request for an endpoint on behalf of the LDD. +// No completion to the PIL occurs. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::CancelEndpointWrite(%d)", aRealEndpoint)); + + if (!IS_IN_ENDPOINT(aRealEndpoint)) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: !IS_IN_ENDPOINT(%d)", aRealEndpoint)); + return KErrArgument; + } + TEndpoint* const ep = &iEndpoints[aRealEndpoint]; + if (ep->iTxBuf == NULL) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > WARNING: iEndpoints[%d].iTxBuf == NULL", aRealEndpoint)); + return KErrNone; + } + + // TO DO (optional): Flush the Ep's Tx FIFO here, if possible. + + ep->iTxBuf = NULL; + ep->iTransmitted = 0; + ep->iNoBuffer = EFalse; + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::SetupEndpointZeroRead() +// +// Sets up an Ep0 read request (own function due to Ep0's special status). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::SetupEndpointZeroRead")); + + TEndpoint* const ep = &iEndpoints[KEp0_Out]; + if (ep->iRxBuf != NULL) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > WARNING: iEndpoints[%d].iRxBuf != NULL", KEp0_Out)); + return KErrGeneral; + } + ep->iRxBuf = iEp0_RxBuf; + ep->iReceived = 0; + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::SetupEndpointZeroWrite(const TUint8* aBuffer, TInt aLength, TBool aZlpReqd) +// +// Sets up an Ep0 write request (own function due to Ep0's special status). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::SetupEndpointZeroWrite")); + + TEndpoint* const ep = &iEndpoints[KEp0_In]; + if (ep->iTxBuf != NULL) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: iEndpoints[%d].iTxBuf != NULL", KEp0_In)); + return KErrGeneral; + } + ep->iTxBuf = aBuffer; + ep->iTransmitted = 0; + ep->iLength = aLength; + ep->iZlpReqd = aZlpReqd; + ep->iRequest = NULL; + Ep0Transmit(); + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::SendEp0ZeroByteStatusPacket() +// +// Sets up an Ep0 write request for zero bytes. +// This is a separate function because no data transfer is involved here. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::SendEp0ZeroByteStatusPacket")); + + // This is possibly a bit tricky. When this function is called it just means that the higher layer wants a + // ZLP to be sent. Whether we actually send one manually here depends on a number of factors, as the + // current Ep0 state (i.e. the stage of the Ep0 Control transfer), and, in case the hardware handles some + // ZLPs itself, whether it might already handle this one. + + // Here is an example of what the checking of the conditions might look like: + +#ifndef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST + if ((!iEp0ReceivedNonStdRequest && iEp0State == EP0_IN_DATA_PHASE) || +#else + if ((!iEp0ReceivedNonStdRequest && iEp0State != EP0_IDLE) || +#endif +#ifdef USB_SUPPORTS_PREMATURE_STATUS_IN + (iEp0ReceivedNonStdRequest && iEp0State != EP0_OUT_DATA_PHASE)) +#else + (iEp0ReceivedNonStdRequest)) +#endif + { + // TO DO: Arrange for the sending of a ZLP here. + } + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::StallEndpoint(TInt aRealEndpoint) +// +// Stalls an endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::StallEndpoint(%d)", aRealEndpoint)); + + if (IS_ISO_ENDPOINT(aRealEndpoint)) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Iso endpoint cannot be stalled")); + return KErrArgument; + } + + // TO DO: Stall the endpoint here. + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::ClearStallEndpoint(TInt aRealEndpoint) +// +// Clears the stall condition of an endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::ClearStallEndpoint(%d)", aRealEndpoint)); + + if (IS_ISO_ENDPOINT(aRealEndpoint)) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Iso endpoint cannot be unstalled")); + return KErrArgument; + } + + // TO DO: De-stall the endpoint here. + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::EndpointStallStatus(TInt aRealEndpoint) const +// +// Reports the stall status of an endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::EndpointStallStatus(%d)", aRealEndpoint)); + + if (IS_ISO_ENDPOINT(aRealEndpoint)) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Iso endpoint has no stall status")); + return KErrArgument; + } + + // TO DO: Query endpoint stall status here. The return value should reflect the actual state. + return ETrue; + } + + +TInt TNaviEngineAsspUsbcc::EndpointErrorStatus(TInt aRealEndpoint) const +// +// Reports the error status of an endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::EndpointErrorStatus(%d)", aRealEndpoint)); + + if (!IS_VALID_ENDPOINT(aRealEndpoint)) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: !IS_VALID_ENDPOINT(%d)", aRealEndpoint)); + return KErrArgument; + } + + // TO DO: Query endpoint error status here. The return value should reflect the actual state. + // With some UDCs there is no way of inquiring the endpoint error status; say 'ETrue' in that case. + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::ResetDataToggle(TInt aRealEndpoint) +// +// Resets to zero the data toggle bit of an endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::ResetDataToggle(%d)", aRealEndpoint)); + + // TO DO: Reset the endpoint's data toggle bit here. + // With some UDCs there is no way to individually reset the endpoint's toggle bits; just return KErrNone + // in that case. + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::SynchFrameNumber() const +// +// For use with isochronous endpoints only. Causes the SOF frame number to be returned. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::SynchFrameNumber")); + + // TO DO: Query and return the SOF frame number here. + return 0; + } + + +void TNaviEngineAsspUsbcc::SetSynchFrameNumber(TInt aFrameNumber) +// +// For use with isochronous endpoints only. Causes the SOF frame number to be stored. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::SetSynchFrameNumber(%d)", aFrameNumber)); + + // We should actually store this number somewhere. But the PIL always sends '0x00' + // in response to a SYNCH_FRAME request... + // TO DO: Store the frame number. Alternatively (until SYNCH_FRAME request specification changes): Do + // nothing. + } + + +TInt TNaviEngineAsspUsbcc::StartUdc() +// +// Called to initialize the device controller hardware before any operation can be performed. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::StartUdc")); + + if (iInitialized) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: UDC already initialised")); + return KErrNone; + } + + // Disable UDC (might also reset the entire design): + UdcDisable(); + + // Enable UDC's clock: + // TO DO: Enable UDC's clock here. + + // Even if only one USB feature has been enabled, we later need to undo it: + iInitialized = ETrue; + + // Bind & enable the UDC interrupt + if (SetupUdcInterrupt() != KErrNone) + { + return KErrGeneral; + } + + // Write meaningful values to some registers: + InitialiseUdcRegisters(); + + // Finally, turn on the UDC: + UdcEnable(); + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::StopUdc() +// +// Basically, makes undone what happened in StartUdc. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::StopUdc")); + + if (!iInitialized) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: UDC not initialized")); + return KErrNone; + } + + // Disable UDC: + UdcDisable(); + + // Mask (disable) Reset interrupt: + // TO DO: Mask (disable) the USB Reset interrupt here. + + // Disable & unbind the UDC interrupt: + ReleaseUdcInterrupt(); + + // Finally turn off UDC's clock: + // TO DO: Disable UDC's clock here. + + // Only when all USB features have been disabled we'll call it a day: + iInitialized = EFalse; + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::UdcConnect() +// +// Connects the UDC to the bus under software control. How this is achieved depends on the UDC; the +// functionality might also be part of the Variant component (instead of the ASSP). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::UdcConnect")); + + // Here: A call into the Variant-provided function. + return iAssp->UsbConnect(); + } + + +TInt TNaviEngineAsspUsbcc::UdcDisconnect() +// +// Disconnects the UDC from the bus under software control. How this is achieved depends on the UDC; the +// functionality might also be part of the Variant component (instead of the ASSP). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::UdcDisconnect")); + + // Here: A call into the Variant-provided function. + return iAssp->UsbDisconnect(); + } + + +TBool TNaviEngineAsspUsbcc::UsbConnectionStatus() const +// +// Returns a value showing the USB cable connection status of the device. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::UsbConnectionStatus")); + + return iCableConnected; + } + + +TBool TNaviEngineAsspUsbcc::UsbPowerStatus() const +// +// Returns a truth value showing whether VBUS is currently powered or not. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::UsbPowerStatus")); + + return iBusIsPowered; + } + + +TBool TNaviEngineAsspUsbcc::DeviceSelfPowered() const +// +// Returns a truth value showing whether the device is currently self-powered or not. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::DeviceSelfPowered")); + + // TO DO: Query and return self powered status here. The return value should reflect the actual state. + // (This can be always 'ETrue' if the UDC does not support bus-powered devices.) + return ETrue; + } + + +const TUsbcEndpointCaps* TNaviEngineAsspUsbcc::DeviceEndpointCaps() const +// +// Returns a pointer to an array of elements, each of which describes the capabilities of one endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::DeviceEndpointCaps")); + __KTRACE_OPT(KUSB, Kern::Printf(" > Ep: Sizes Mask, Types Mask")); + __KTRACE_OPT(KUSB, Kern::Printf(" > --------------------------")); + for (TInt i = 0; i < KUsbTotalEndpoints; ++i) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > %02d: 0x%08x, 0x%08x", + i, DeviceEndpoints[i].iSizes, DeviceEndpoints[i].iTypesAndDir)); + } + return DeviceEndpoints; + } + + +TInt TNaviEngineAsspUsbcc::DeviceTotalEndpoints() const +// +// Returns the element number of the endpoints array a pointer to which is returned by DeviceEndpointCaps. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::DeviceTotalEndpoints")); + + return KUsbTotalEndpoints; + } + + +TBool TNaviEngineAsspUsbcc::SoftConnectCaps() const +// +// Returns a truth value showing whether or not there is the capability to disconnect and re-connect the D+ +// line under software control. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::SoftConnectCaps")); + + return iSoftwareConnectable; + } + + +void TNaviEngineAsspUsbcc::Suspend() +// +// Called by the PIL after a Suspend event has been reported (by us). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::Suspend")); + + // TO DO (optional): Implement here anything the device might require after bus SUSPEND signalling. + } + + +void TNaviEngineAsspUsbcc::Resume() +// +// Called by the PIL after a Resume event has been reported (by us). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::Resume")); + + // TO DO (optional): Implement here anything the device might require after bus RESUME signalling. + } + + +void TNaviEngineAsspUsbcc::Reset() +// +// Called by the PIL after a Reset event has been reported (by us). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::Reset")); + + // This does not really belong here, but has to do with the way the PIL sets + // up Ep0 reads and writes. + TEndpoint* ep = &iEndpoints[0]; + ep->iRxBuf = NULL; + ++ep; + ep->iTxBuf = NULL; + // Idle + Ep0NextState(EP0_IDLE); + + // TO DO (optional): Implement here anything the device might require after bus RESET signalling. + + // Write meaningful values to some registers + InitialiseUdcRegisters(); + UdcEnable(); + if (iEp0Configured) + EnableEndpointInterrupt(0); + } + + +// --- TNaviEngineAsspUsbcc private -------------------------------------------------- + +void TNaviEngineAsspUsbcc::InitialiseUdcRegisters() +// +// Called after every USB Reset etc. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::InitialiseUdcRegisters")); + + // Unmask Suspend interrupt + // TO DO: Unmask Suspend interrupt here. + + // Unmask Resume interrupt + // TO DO: Unmask Resume interrupt here. + + // Unmask Start-of-Frame (SOF) interrupt + // TO DO (optional): Unmask SOF interrupt here. + + // Disable interrupt requests for all endpoints + // TO DO: Disable interrupt requests for all endpoints here. + } + + +void TNaviEngineAsspUsbcc::UdcEnable() +// +// Enables the UDC for USB transmission or reception. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::UdcEnable")); + + // TO DO: Do whatever is necessary to enable the UDC here. This might include enabling (unmasking) + // the USB Reset interrupt, setting a UDC enable bit, etc. + } + + +void TNaviEngineAsspUsbcc::UdcDisable() +// +// Disables the UDC. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::UdcDisable")); + + // TO DO: Do whatever is necessary to disable the UDC here. This might include disabling (masking) + // the USB Reset interrupt, clearing a UDC enable bit, etc. + } + + +void TNaviEngineAsspUsbcc::EnableEndpointInterrupt(TInt aEndpoint) +// +// Enables interrupt requests for an endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::EnableEndpointInterrupt(%d)", aEndpoint)); + + // Enable (unmask) interrupt requests for this endpoint: + // TO DO: Enable interrupt requests for aEndpoint here. + } + + +void TNaviEngineAsspUsbcc::DisableEndpointInterrupt(TInt aEndpoint) +// +// Disables interrupt requests for an endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::DisableEndpointInterrupt(%d)", aEndpoint)); + + // Disable (mask) interrupt requests for this endpoint: + // TO DO: Disable interrupt requests for aEndpoint here. + } + + +void TNaviEngineAsspUsbcc::ClearEndpointInterrupt(TInt aEndpoint) +// +// Clears a pending interrupt request for an endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::ClearEndpointInterrupt(%d)", aEndpoint)); + + // Clear (reset) pending interrupt request for this endpoint: + // TO DO: Clear interrupt request for aEndpoint here. + } + + +void TNaviEngineAsspUsbcc::Ep0IntService() +// +// ISR for endpoint zero interrupt. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::Ep0IntService")); + + // TO DO: Enquire about Ep0 status & the interrupt cause here. Depending on the event and the Ep0 state, + // one or more of the following functions might then be called: + Ep0Cancel(); + Ep0ReadSetupPkt(); + Ep0EndXfer(); + Ep0PrematureStatusOut(); + Ep0Transmit(); + Ep0StatusIn(); + Ep0Receive(); + ClearStallEndpoint(0); + + ClearEndpointInterrupt(0); + return; + } + + +void TNaviEngineAsspUsbcc::Ep0ReadSetupPkt() +// +// Called from the Ep0 ISR when a new Setup packet has been received. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::Ep0ReadSetupPkt")); + + TEndpoint* const ep = &iEndpoints[KEp0_Out]; + TUint8* buf = ep->iRxBuf; + if (!buf) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: No Ep0 Rx buffer available (1)")); + StallEndpoint(KEp0_Out); + return; + } + + // TO DO: Read Setup packet data from Rx FIFO into 'buf' here. + // (In this function we don't need to use "ep->iReceived" since Setup packets + // are always 8 bytes long.) + + // Upcall into PIL to determine next Ep0 state: + TUsbcEp0State state = EnquireEp0NextState(ep->iRxBuf); + + if (state == EEp0StateStatusIn) + { + Ep0NextState(EP0_IDLE); // Ep0 No Data + } + else if (state == EEp0StateDataIn) + { + Ep0NextState(EP0_IN_DATA_PHASE); // Ep0 Control Read + } + else + { + Ep0NextState(EP0_OUT_DATA_PHASE); // Ep0 Control Write + } + + ep->iRxBuf = NULL; + const TInt r = Ep0RequestComplete(KEp0_Out, 8, KErrNone); + + // Don't finish (proceed) if request completion returned 'KErrNotFound'! + if (!(r == KErrNone || r == KErrGeneral)) + { + DisableEndpointInterrupt(0); + } + + // TO DO (optional): Clear Ep0 Setup condition flags here. + +#ifdef USB_SUPPORTS_PREMATURE_STATUS_IN + if (iEp0State == EP0_OUT_DATA_PHASE) + { + // Allow for a premature STATUS IN + // TO DO: Arrange for the sending of a ZLP here. + } +#endif + } + + +void TNaviEngineAsspUsbcc::Ep0ReadSetupPktProceed() +// +// Called by the PIL to signal that it has finished processing a received Setup packet and that the PSL can +// now prepare itself for the next Ep0 reception (for instance by re-enabling the Ep0 interrupt). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::Ep0ReadSetupPktProceed")); + + EnableEndpointInterrupt(0); + } + + +void TNaviEngineAsspUsbcc::Ep0Receive() +// +// Called from the Ep0 ISR when a data packet has been received. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::Ep0Receive")); + + TEndpoint* const ep = &iEndpoints[KEp0_Out]; + TUint8* buf = ep->iRxBuf; + if (!buf) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: No Ep0 Rx buffer available (2)")); + StallEndpoint(KEp0_Out); + return; + } + + TInt n = 0; + // TO DO: Read packet data from Rx FIFO into 'buf' and update 'n' (# of received bytes) here. + + ep->iReceived = n; + ep->iRxBuf = NULL; + const TInt r = Ep0RequestComplete(KEp0_Out, n, KErrNone); + + // Don't finish (proceed) if request was 'KErrNotFound'! + if (!(r == KErrNone || r == KErrGeneral)) + { + DisableEndpointInterrupt(0); + } + + // TO DO (optional): Clear Ep0 Rx condition flags here. + +#ifdef USB_SUPPORTS_PREMATURE_STATUS_IN + // Allow for a premature STATUS IN + // TO DO: Arrange for the sending of a ZLP here. +#endif + } + + +void TNaviEngineAsspUsbcc::Ep0ReceiveProceed() +// +// Called by the PIL to signal that it has finished processing a received Ep0 data packet and that the PSL can +// now prepare itself for the next Ep0 reception (for instance by re-enabling the Ep0 interrupt). +// + { + Ep0ReadSetupPktProceed(); + } + + +void TNaviEngineAsspUsbcc::Ep0Transmit() +// +// Called from either the Ep0 ISR or the PIL when a data packet has been or is to be transmitted. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::Ep0Transmit")); + + if (iEp0State != EP0_IN_DATA_PHASE) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > WARNING: Invalid Ep0 state when trying to handle EP0 IN")); + // TO DO (optional): Do something about this warning. + } + + TEndpoint* const ep = &iEndpoints[KEp0_In]; + const TUint8* buf = ep->iTxBuf; + if (!buf) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > No Tx buffer available: returning")); + return; + } + const TInt t = ep->iTransmitted; // already transmitted + buf += t; + TInt n = 0; // now transmitted + + // TO DO: Write packet data (if any) into Tx FIFO from 'buf' and update 'n' (# of tx'ed bytes) here. + + ep->iTransmitted += n; + // coverity[dead_error_condition] + if (n == KEp0MaxPktSz) + { + if (ep->iTransmitted == ep->iLength && !(ep->iZlpReqd)) + Ep0NextState(EP0_END_XFER); + } + else if (n && n != KEp0MaxPktSz) + { + // Send off the data + __ASSERT_DEBUG((ep->iTransmitted == ep->iLength), + Kern::Printf(" > ERROR: Short packet in mid-transfer")); + Ep0NextState(EP0_END_XFER); + // TO DO: Send off the data here. + } + else // if (n == 0) + { + __ASSERT_DEBUG((ep->iTransmitted == ep->iLength), + Kern::Printf(" > ERROR: Nothing transmitted but still not finished")); + if (ep->iZlpReqd) + { + // Send a zero length packet + ep->iZlpReqd = EFalse; + Ep0NextState(EP0_END_XFER); + // TO DO: Arrange for the sending of a ZLP here. + } + else + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: nothing transmitted & no ZLP req'd")); + } + } + } + + +void TNaviEngineAsspUsbcc::Ep0EndXfer() +// +// Called at the end of a Ep0 Control transfer. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::Ep0EndXfer")); + + // TO DO (optional): Clear Ep0 Rx condition flags here. + + Ep0NextState(EP0_IDLE); + TEndpoint* const ep = &iEndpoints[KEp0_In]; + ep->iTxBuf = NULL; + (void) Ep0RequestComplete(KEp0_In, ep->iTransmitted, KErrNone); + } + + +void TNaviEngineAsspUsbcc::Ep0Cancel() +// +// Called when an ongoing Ep0 Control transfer has to be aborted prematurely (for instance when receiving a +// new Setup packet before the processing of the old one has completed). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::Ep0Cancel")); + + Ep0NextState(EP0_IDLE); + TEndpoint* const ep = &iEndpoints[KEp0_In]; + if (ep->iTxBuf) + { + ep->iTxBuf = NULL; + const TInt err = (ep->iTransmitted == ep->iLength) ? KErrNone : KErrCancel; + (void) Ep0RequestComplete(KEp0_In, ep->iTransmitted, err); + } + } + + +void TNaviEngineAsspUsbcc::Ep0PrematureStatusOut() +// +// Called when an ongoing Ep0 Control transfer encounters a premature Status OUT condition. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::Ep0PrematureStatusOut")); + + // TO DO (optional): Clear Ep0 Rx condition flags here. + + Ep0NextState(EP0_IDLE); + + // TO DO (optional): Flush the Ep0 Tx FIFO here, if possible. + + TEndpoint* const ep = &iEndpoints[KEp0_In]; + if (ep->iTxBuf) + { + ep->iTxBuf = NULL; + (void) Ep0RequestComplete(KEp0_In, ep->iTransmitted, KErrPrematureEnd); + } + } + + +void TNaviEngineAsspUsbcc::Ep0StatusIn() +// +// Called when an ongoing Ep0 Control transfer moves to a Status IN stage. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::Ep0StatusIn")); + + Ep0NextState(EP0_IDLE); + } + + +void TNaviEngineAsspUsbcc::BulkTransmit(TInt aEndpoint) +// +// Endpoint 1 (BULK IN). +// Called from either the Ep ISR or the PIL when a data packet has been or is to be transmitted. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::BulkTransmit(%d)", aEndpoint)); + + // TO DO: Enquire about Ep status here. + + const TInt idx = 3; // only in our special case of course! + TEndpoint* const ep = &iEndpoints[idx]; + const TUint8* buf = ep->iTxBuf; + if (!buf) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: No Tx buffer has been set up")); + DisableEndpointInterrupt(aEndpoint); + ep->iDisabled = ETrue; + ClearEndpointInterrupt(aEndpoint); + return; + } + const TInt t = ep->iTransmitted; // already transmitted + const TInt len = ep->iLength; // to be sent in total + // (len || ep->iPackets): Don't complete for a zero bytes request straight away. + if (t >= len && (len || ep->iPackets)) + { + if (ep->iZlpReqd) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > 'Transmit Short Packet' explicitly")); + // TO DO: Arrange for the sending of a ZLP here. + ep->iZlpReqd = EFalse; + } + else + { + __KTRACE_OPT(KUSB, Kern::Printf(" > All data sent: %d --> completing", len)); + ep->iTxBuf = NULL; + ep->iRequest->iTxBytes = ep->iTransmitted; + ep->iRequest->iError = KErrNone; + EndpointRequestComplete(ep->iRequest); + ep->iRequest = NULL; + } + } + else + { + buf += t; + TInt left = len - t; // left in total + TInt n = (left >= KBlkMaxPktSz) ? KBlkMaxPktSz : left; // now to be transmitted + __KTRACE_OPT(KUSB, Kern::Printf(" > About to send %d bytes (%d bytes left in total)", n, left)); + + // TO DO: Write data into Tx FIFO from 'buf' here. + + ep->iTransmitted += n; + ep->iPackets++; // only used for (len == 0) case + left -= n; // (still) left in total + if (n < KBlkMaxPktSz) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > 'Transmit Short Packet' implicitly")); + // TO DO: Arrange for the sending of a ZLP here. + ep->iZlpReqd = EFalse; + } + // If double-buffering is available, it might be possible to stick a second packet + // into the FIFO here. + + // TO DO (optional): Send another packet if possible (& available) here. + } + + ClearEndpointInterrupt(aEndpoint); + } + + + +void TNaviEngineAsspUsbcc::BulkReceive(TInt aEndpoint) +// +// Endpoint 2 (BULK OUT) (This one is called in an ISR.) +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::BulkReceive(%d)", aEndpoint)); + + // TO DO: Enquire about Ep status here. + const TUint32 status = *(TUint32*)0xdefaced; // bogus + + const TInt idx = 4; // only in our special case of course! + TEndpoint* const ep = &iEndpoints[idx]; + TUint8* buf = ep->iRxBuf; + if (!buf) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > No Rx buffer available: setting iNoBuffer")); + ep->iNoBuffer = ETrue; + DisableEndpointInterrupt(aEndpoint); + ep->iDisabled = ETrue; + ClearEndpointInterrupt(aEndpoint); + return; + } + TInt bytes = 0; + const TInt r = ep->iReceived; // already received + // TO DO: Check whether a ZLP was received here: + if (status & 1) // some condition + { + __KTRACE_OPT(KUSB, Kern::Printf(" > received zero-length packet")); + } + else if (status & 2) // some other condition + { + // TO DO: Get number of bytes received here. + bytes = *(TUint32*)0xdadadada; // bogus + __KTRACE_OPT(KUSB, Kern::Printf(" > Bulk received: %d bytes", bytes)); + if (r + bytes > ep->iLength) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > not enough space in rx buffer: setting iNoBuffer")); + ep->iNoBuffer = ETrue; + StopRxTimer(ep); + *ep->iPacketSize = ep->iReceived; + RxComplete(ep); + + // TO DO (optional): Clear Ep Rx condition flags here. + + ClearEndpointInterrupt(aEndpoint); + return; + } + buf += r; // set buffer pointer + + // TO DO: Read 'bytes' bytes from Rx FIFO into 'buf' here. + + ep->iReceived += bytes; + } + else + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Inconsistent Ep%d state", aEndpoint)); + + // TO DO (optional): Clear Ep Rx condition flags here. + + ClearEndpointInterrupt(aEndpoint); + return; + } + + if (bytes == 0) + { + // ZLPs must be recorded separately + const TInt i = ep->iReceived ? 1 : 0; + ep->iPacketIndex[i] = r; + ep->iPacketSize[i] = 0; + // If there were data packets before: total packets reported 1 -> 2 + ep->iPackets += i; + } + + if ((bytes < KBlkMaxPktSz) || + (ep->iReceived == ep->iLength)) + { + StopRxTimer(ep); + *ep->iPacketSize = ep->iReceived; + RxComplete(ep); + // since we have no buffer any longer we disable interrupts: + DisableEndpointInterrupt(aEndpoint); + ep->iDisabled = ETrue; + } + else + { + if (!ep->iRxTimerSet) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > setting rx timer")); + ep->iRxTimerSet = ETrue; + ep->iRxTimer.OneShot(KRxTimerTimeout); + } + else + { + ep->iRxMoreDataRcvd = ETrue; + } + } + + // TO DO (optional): Clear Ep Rx condition flags here. + + ClearEndpointInterrupt(aEndpoint); + } + + +void TNaviEngineAsspUsbcc::BulkReadRxFifo(TInt aEndpoint) +// +// Endpoint 2 (BULK OUT) (This one is called w/o interrupt to be served.) +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::BulkReadRxFifo(%d)", aEndpoint)); + + // TO DO: Enquire about Ep status here. + const TUint32 status = *(TUint32*)0xdefaced; // bogus + + const TInt idx = 4; // only in our special case of course! + TEndpoint* const ep = &iEndpoints[idx]; + TUint8* buf = ep->iRxBuf; + if (!buf) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: No Rx buffer has been set up")); + return; + } + TInt bytes = 0; + const TInt r = ep->iReceived; // already received + // TO DO: Check whether a ZLP was received here: + if (status & 1) // some condition + { + __KTRACE_OPT(KUSB, Kern::Printf(" > received zero-length packet")); + } + else if (status & 2) // some other condition + { + // TO DO: Get number of bytes received here. + bytes = *(TUint32*)0xdadadada; // bogus + __KTRACE_OPT(KUSB, Kern::Printf(" > Bulk received: %d bytes", bytes)); + if (r + bytes > ep->iLength) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > not enough space in rx buffer: setting iNoBuffer")); + ep->iNoBuffer = ETrue; + *ep->iPacketSize = ep->iReceived; + RxComplete(ep); + return; + } + buf += r; // set buffer pointer + + // TO DO: Read 'bytes' bytes from Rx FIFO into 'buf' here. + + ep->iReceived += bytes; + } + else + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Inconsistent Ep%d state", aEndpoint)); + return; + } + + if (bytes == 0) + { + // ZLPs must be recorded separately + const TInt i = ep->iReceived ? 1 : 0; + ep->iPacketIndex[i] = r; + ep->iPacketSize[i] = 0; + // If there were data packets before: total packets reported 1 -> 2 + ep->iPackets += i; + } + + if ((bytes < KBlkMaxPktSz) || + (ep->iReceived == ep->iLength)) + { + *ep->iPacketSize = ep->iReceived; + RxComplete(ep); + } + else + { + if (!ep->iRxTimerSet) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > setting rx timer")); + ep->iRxTimerSet = ETrue; + ep->iRxTimer.OneShot(KRxTimerTimeout); + } + else + { + ep->iRxMoreDataRcvd = ETrue; + } + } + + // TO DO (optional): Clear Ep Rx condition flags here. + + } + + +void TNaviEngineAsspUsbcc::IsoTransmit(TInt aEndpoint) +// +// Endpoint 3 (ISOCHRONOUS IN). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::IsoTransmit(%d)", aEndpoint)); + + // TO DO: Write data to endpoint FIFO. Might be similar to BulkTransmit. + + } + + +void TNaviEngineAsspUsbcc::IsoReceive(TInt aEndpoint) +// +// Endpoint 4 (ISOCHRONOUS OUT) (This one is called in an ISR.) +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::IsoReceive(%d)", aEndpoint)); + + // TO DO: Read data from endpoint FIFO. Might be similar to BulkReceive. + } + + +void TNaviEngineAsspUsbcc::IsoReadRxFifo(TInt aEndpoint) +// +// Endpoint 4 (ISOCHRONOUS OUT) (This one is called w/o interrupt to be served.) +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::IsoReadRxFifo(%d)", aEndpoint)); + + // TO DO: Read data from endpoint FIFO. Might be similar to BulkReadRxFifo. + } + + +void TNaviEngineAsspUsbcc::IntTransmit(TInt aEndpoint) +// +// Endpoint 5 (INTERRUPT IN). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::IntTransmit(%d)", aEndpoint)); + + // TO DO: Write data to endpoint FIFO. Might be similar to BulkTransmit. + } + + +void TNaviEngineAsspUsbcc::RxComplete(TEndpoint* aEndpoint) +// +// Called at the end of an Rx (OUT) transfer to complete to the PIL. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::RxComplete")); + + TUsbcRequestCallback* const req = aEndpoint->iRequest; + + __ASSERT_DEBUG((req != NULL), Kern::Fault(KUsbPanicCat, __LINE__)); + + aEndpoint->iRxBuf = NULL; + aEndpoint->iRxTimerSet = EFalse; + aEndpoint->iRxMoreDataRcvd = EFalse; + req->iRxPackets = aEndpoint->iPackets; + req->iError = aEndpoint->iLastError; + EndpointRequestComplete(req); + aEndpoint->iRequest = NULL; + } + + +void TNaviEngineAsspUsbcc::StopRxTimer(TEndpoint* aEndpoint) +// +// Stops (cancels) the Rx timer for an endpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::StopRxTimer")); + + if (aEndpoint->iRxTimerSet) + { + __KTRACE_OPT(KUSB, Kern::Printf(" > stopping rx timer")); + aEndpoint->iRxTimer.Cancel(); + aEndpoint->iRxTimerSet = EFalse; + } + } + + +void TNaviEngineAsspUsbcc::EndpointIntService(TInt aEndpoint) +// +// ISR for endpoint interrupts. +// Note: the aEndpoint here is a "hardware endpoint", not a aRealEndpoint. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::EndpointIntService(%d)", aEndpoint)); + + switch (aEndpoint) + { + case 0: + Ep0IntService(); + break; + case 1: + BulkTransmit(aEndpoint); + break; + case 2: + BulkReceive(aEndpoint); + break; + case 3: + IsoTransmit(aEndpoint); + break; + case 4: + IsoReceive(aEndpoint); + break; + case 5: + IntTransmit(aEndpoint); + break; + default: + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Endpoint not found")); + break; + } + } + + +TInt TNaviEngineAsspUsbcc::ResetIntService() +// +// ISR for a USB Reset event interrupt. +// This function returns a value which can be used on the calling end to decide how to proceed. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::ResetIntService")); + + // Clear an interrupt: + // TO DO: Clear reset interrupt flag here. + + // TO DO (optional): Enquire about special conditions and possibly return here. + + DeviceEventNotification(EUsbEventReset); + + return KErrNone; + } + + +void TNaviEngineAsspUsbcc::SuspendIntService() +// +// ISR for a USB Suspend event interrupt. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::SuspendIntService")); + + // Clear an interrupt: + // TO DO: Clear suspend interrupt flag here. + + DeviceEventNotification(EUsbEventSuspend); + } + + +void TNaviEngineAsspUsbcc::ResumeIntService() +// +// ISR for a USB Resume event interrupt. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::ResumeIntService")); + + // Clear an interrupt: + // TO DO: Clear resume interrupt flag here. + + DeviceEventNotification(EUsbEventResume); + } + + +void TNaviEngineAsspUsbcc::SofIntService() +// +// ISR for a USB Start-of-Frame event interrupt. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::SofIntService")); + + // Clear an interrupt: + // TO DO: Clear SOF interrupt flag here. + + // TO DO (optional): Do something about the SOF condition. + } + + +void TNaviEngineAsspUsbcc::UdcInterruptService() +// +// Main UDC ISR - determines the cause of the interrupt, clears the condition, dispatches further for service. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::InterruptService")); + + // TO DO: Find the cause of the interrupt (possibly querying a number of status registers) here. + + // Determine the type of UDC interrupt & then serve it: + // (The following operations are of course EXAMPLES only.) + volatile const TUint32* const status_reg = (TUint32*) 0xdefaced; + const TUint32 status = *status_reg; + enum {reset_interrupt, suspend_interrupt, resume_interrupt, sof_interrupt, ep_interrupt}; + + // Reset interrupt + if (status & reset_interrupt) + { + ResetIntService(); + } + + // Suspend interrupt + if (status & suspend_interrupt) + { + SuspendIntService(); + } + + // Resume interrupt + if (status & resume_interrupt) + { + ResumeIntService(); + } + + // Start-of-Frame interrupt + if (status & sof_interrupt) + { + SofIntService(); + } + + // Endpoint interrupt + if (status & ep_interrupt) + { + const TInt ep = status & 0xffff0000; + { + EndpointIntService(ep); + } + } + } + + +void TNaviEngineAsspUsbcc::Ep0NextState(TEp0State aNextState) +// +// Moves the Ep0 state to aNextState. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::Ep0NextState")); + + iEp0State = aNextState; + } + + +void TNaviEngineAsspUsbcc::UdcIsr(TAny* aPtr) +// +// This is the static ASSP first-level UDC interrupt service routine. It dispatches the call to the +// actual controller's ISR. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::UdcIsr")); + + static_cast(aPtr)->UdcInterruptService(); + } + + +TInt TNaviEngineAsspUsbcc::UsbClientConnectorCallback(TAny* aPtr) +// +// This function is called in ISR context by the Variant's UsbClientConnectorInterruptService. +// (This function is static.) +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::UsbClientConnectorCallback")); + + TNaviEngineAsspUsbcc* const ptr = static_cast(aPtr); + ptr->iCableConnected = ptr->iAssp->UsbClientConnectorInserted(); +#ifdef _DEBUG + _LIT(KIns, "inserted"); + _LIT(KRem, "removed"); + __KTRACE_OPT(KUSB, Kern::Printf(" > USB cable now %lS", ptr->iCableConnected ? &KIns : &KRem)); +#endif + if (ptr->iCableConnected) + { + ptr->DeviceEventNotification(EUsbEventCableInserted); + } + else + { + ptr->DeviceEventNotification(EUsbEventCableRemoved); + } + + return KErrNone; + } + + +TInt TNaviEngineAsspUsbcc::SetupUdcInterrupt() +// +// Registers and enables the UDC interrupt (ASSP first level interrupt). +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::SetupUdcInterrupt")); + + // Register UDC interrupt: + TInt irqh = Interrupt::Bind(EAsspIntIdUsb, UdcIsr, this); + if (irqh < 0) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Binding UDC interrupt failed")); + return irqh; + } + + // Enable UDC interrupt: + Interrupt::Enable(irqh); + + return KErrNone; + } + + +void TNaviEngineAsspUsbcc::ReleaseUdcInterrupt() +// +// Disables and unbinds the UDC interrupt. +// + { + __KTRACE_OPT(KUSB, Kern::Printf("TNaviEngineAsspUsbcc::ReleaseUdcInterrupt")); + + // Disable UDC interrupt: + Interrupt::Disable(EAsspIntIdUsb); + + // Unregister UDC interrupt: + Interrupt::Unbind(EAsspIntIdUsb); + } + + +// +// --- DLL Exported Function -------------------------------------------------- +// + +DECLARE_STANDARD_EXTENSION() +// +// Creates and initializes a new USB client controller object on the kernel heap. +// + { + __KTRACE_OPT(KUSB, Kern::Printf(" > Initializing USB client support (Udcc)...")); + + TNaviEngineAsspUsbcc* const usbcc = new TNaviEngineAsspUsbcc(); + if (!usbcc) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Memory allocation for TNaviEngineAsspUsbcc failed")); + return KErrNoMemory; + } + + TInt r; + if ((r = usbcc->Construct()) != KErrNone) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: Construction of TNaviEngineAsspUsbcc failed (%d)", r)); + delete usbcc; + return r; + } + + if (usbcc->RegisterUdc(0) == NULL) + { + __KTRACE_OPT(KPANIC, Kern::Printf(" Error: PIL registration of PSL failed")); + delete usbcc; + return KErrGeneral; + } + + __KTRACE_OPT(KUSB, Kern::Printf(" > Initializing USB client support: Done")); + + return KErrNone; + } + + +// --- EOF -------------------------------------------------------------------- diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/pa_usbc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/pa_usbc.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,257 @@ +/* +* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\pa_usbc.h +* Platform-dependent USB client controller layer (USB PSL). +* +*/ + + + + +#ifndef __PA_USBC_H__ +#define __PA_USBC_H__ + + +// This is the header file for the implementation of the USB driver PSL layer for an imaginary USB client +// (device) controller. +// For simplicity's sake we assume the following endpoint layout of the controller. +// We have 5 endpoints in total - two Bulk endpoints (IN and OUT), two Isochronous endpoint (IN and OUT), +// one Interrupt endpoint (IN), and of course endpoint zero (Ep0). +// +// This is the mapping of "Hardware Endpoint Numbers" to "Real Endpoints" (and thus is also +// used as the array index for our local TNaviEngineAsspUsbcc::iEndpoints[]): +// +// 0 - 0 (Ep0 OUT) +// 0 - 1 (Ep0 IN) +// 1 - 3 (Bulk IN, Address 0x11, -> EpAddr2Idx(0x11) = 3) +// 2 - 4 (Bulk OUT, Address 0x02, -> EpAddr2Idx(0x02) = 4) +// 3 - 7 (Iso IN, Address 0x13, -> EpAddr2Idx(0x13) = 7) +// 4 - 8 (Iso OUT, Address 0x04, -> EpAddr2Idx(0x04) = 8) +// 5 - 11 (Int IN, Address 0x15, -> EpAddr2Idx(0x15) = 11) +// +// For the reason why this is so (or rather for the perhaps not so obvious system behind it), +// see the comment at the beginning of \e32\drivers\usbcc\ps_usbc.cpp and also the structure +// DeviceEndpoints[] at the top of pa_usbc.cpp. + +// The total number of endpoints in our local endpoint array: +static const TInt KUsbTotalEndpoints = 12; + +// The numbers used in the following macros are 'aRealEndpoint's (i.e. array indices): +#define IS_VALID_ENDPOINT(x) ((x) > 0 && (x) < KUsbTotalEndpoints) +#define IS_OUT_ENDPOINT(x) ((x) == 0 || (x) == 4 || (x) == 8) +#define IS_IN_ENDPOINT(x) ((x) == 1 || (x) == 3 || (x) == 7 || (x) == 11) +#define IS_BULK_IN_ENDPOINT(x) ((x) == 3) +#define IS_BULK_OUT_ENDPOINT(x) ((x) == 4) +#define IS_BULK_ENDPOINT(x) (IS_BULK_IN_ENDPOINT(x) || IS_BULK_OUT_ENDPOINT(x)) +#define IS_ISO_IN_ENDPOINT(x) ((x) == 7) +#define IS_ISO_OUT_ENDPOINT(x) ((x) == 8) +#define IS_ISO_ENDPOINT(x) (IS_ISO_IN_ENDPOINT(x) || IS_ISO_OUT_ENDPOINT(x)) +#define IS_INT_IN_ENDPOINT(x) ((x) == 11) + +// This takes as an index the TNaviEngineAsspUsbcc::iEndpoints index (== aRealEndpoint) 0..11 +// and returns the hardware endpoint number 0..5 (note that not all input indices are valid; +// these will return -1): +static const TInt TemplateAsspEndpoints[KUsbTotalEndpoints] = + {0, 0, -1, 1, 2, -1, -1, 3, 4, -1, -1, 5}; + +// And here is a function to use the above array: +static inline TInt ArrayIdx2TemplateEp(TInt aRealEndpoint) + { + if (IS_VALID_ENDPOINT(aRealEndpoint)) return TemplateAsspEndpoints[aRealEndpoint]; + else return -1; + } + +// Endpoint max packet sizes +static const TInt KEp0MaxPktSz = 16; // Control +static const TInt KIntMaxPktSz = 8; // Interrupt +static const TInt KBlkMaxPktSz = 64; // Bulk +static const TInt KIsoMaxPktSz = 256; // Isochronous +static const TInt KEp0MaxPktSzMask = KUsbEpSize16; // Control +static const TInt KIntMaxPktSzMask = KUsbEpSize8; // Interrupt +static const TInt KBlkMaxPktSzMask = KUsbEpSize64; // Bulk +static const TInt KIsoMaxPktSzMask = KUsbEpSize256; // Isochronous + +// 1 ms (i.e. the shortest delay possible with the sort of timer used) seems to give +// the best results, both for Bulk and Iso, and also (in the USBRFLCT test program) +// both for loop tests as well as unidirectional transfers. +static const TInt KRxTimerTimeout = 1; // milliseconds + +// Used in descriptors +static const TUint16 KUsbVendorId = KUsbVendorId_Symbian; // Symbian +static const TUint16 KUsbProductId = 0x0666; // bogus... +static const TUint16 KUsbDevRelease = 0x0100; // bogus... (BCD!) +static const TUint16 KUsbLangId = 0x0409; // English (US) Language ID + +// String descriptor default values +static const wchar_t KStringManufacturer[] = L"Symbian Software Ltd."; +static const wchar_t KStringProduct[] = L"NE1_TBVariant USB Test Driver"; +static const wchar_t KStringSerialNo[] = L"0123456789"; +static const wchar_t KStringConfig[] = L"First and Last and Always"; + + +// We use our own Ep0 state enum: +enum TEp0State + { + EP0_IDLE = 0, // These identifiers don't conform to + EP0_OUT_DATA_PHASE = 1, // Symbian's coding standard... ;) + EP0_IN_DATA_PHASE = 2, + EP0_END_XFER = 3, + }; + + +class TNaviEngineAsspUsbcc; +// The lowest level endpoint abstraction +struct TEndpoint + { + TEndpoint(); + static void RxTimerCallback(TAny* aPtr); + // data + TNaviEngineAsspUsbcc* iController; // pointer to controller object + union + { + TUint8* iRxBuf; // where to store / + const TUint8* iTxBuf; // from where to send + }; + union + { + TInt iReceived; // bytes already rx'ed / + TInt iTransmitted; // bytes already tx'ed + }; + TInt iLength; // number of bytes to be transferred + TBool iZlpReqd; // ZeroLengthPacketRequired + TBool iNoBuffer; // no data buffer was available when it was needed + TBool iDisabled; // dto but stronger + TInt iPackets; // number of packets rx'ed or tx'ed + TInt iLastError; // + TUsbcRequestCallback* iRequest; // + NTimer iRxTimer; // + TBool iRxTimerSet; // true if iRxTimer is running + TBool iRxMoreDataRcvd; // true if after setting timer data have arrived + TUsbcPacketArray* iPacketIndex; // actually TUsbcPacketArray (*)[] + TUsbcPacketArray* iPacketSize; // actually TUsbcPacketArray (*)[] + }; + + +// The hardware driver object proper +class TNaviEngine; +class TNaviEngineAsspUsbcc : public DUsbClientController + { +friend void TEndpoint::RxTimerCallback(TAny*); + +public: + TNaviEngineAsspUsbcc(); + TInt Construct(); + virtual ~TNaviEngineAsspUsbcc(); + virtual void DumpRegisters(); + +private: + virtual TInt SetDeviceAddress(TInt aAddress); + virtual TInt ConfigureEndpoint(TInt aRealEndpoint, const TUsbcEndpointInfo& aEndpointInfo); + virtual TInt DeConfigureEndpoint(TInt aRealEndpoint); + virtual TInt AllocateEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource); + virtual TInt DeAllocateEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource); + virtual TBool QueryEndpointResource(TInt aRealEndpoint, TUsbcEndpointResource aResource) const; + virtual TInt OpenDmaChannel(TInt aRealEndpoint); + virtual void CloseDmaChannel(TInt aRealEndpoint); + virtual TInt SetupEndpointRead(TInt aRealEndpoint, TUsbcRequestCallback& aCallback); + virtual TInt SetupEndpointWrite(TInt aRealEndpoint, TUsbcRequestCallback& aCallback); + virtual TInt CancelEndpointRead(TInt aRealEndpoint); + virtual TInt CancelEndpointWrite(TInt aRealEndpoint); + virtual TInt SetupEndpointZeroRead(); + virtual TInt SetupEndpointZeroWrite(const TUint8* aBuffer, TInt aLength, TBool aZlpReqd = EFalse); + virtual TInt SendEp0ZeroByteStatusPacket(); + virtual TInt StallEndpoint(TInt aRealEndpoint); + virtual TInt ClearStallEndpoint(TInt aRealEndpoint); + virtual TInt EndpointStallStatus(TInt aRealEndpoint) const; + virtual TInt EndpointErrorStatus(TInt aRealEndpoint) const; + virtual TInt ResetDataToggle(TInt aRealEndpoint); + virtual TInt SynchFrameNumber() const; + virtual void SetSynchFrameNumber(TInt aFrameNumber); + virtual TInt StartUdc(); + virtual TInt StopUdc(); + virtual TInt UdcConnect(); + virtual TInt UdcDisconnect(); + virtual TBool UsbConnectionStatus() const; + virtual TBool UsbPowerStatus() const; + virtual TBool DeviceSelfPowered() const; + virtual const TUsbcEndpointCaps* DeviceEndpointCaps() const; + virtual TInt DeviceTotalEndpoints() const; + virtual TBool SoftConnectCaps() const; + virtual TBool DeviceStateChangeCaps() const; + virtual void Suspend(); + virtual void Resume(); + virtual void Reset(); + virtual TInt SignalRemoteWakeup(); + virtual void Ep0ReadSetupPktProceed(); + virtual void Ep0ReceiveProceed(); + virtual TDfcQue* DfcQ(TInt aUnit); + +private: + // general + void EnableEndpointInterrupt(TInt aEndpoint); + void DisableEndpointInterrupt(TInt aEndpoint); + void ClearEndpointInterrupt(TInt aEndpoint); + void InitialiseUdcRegisters(); + void UdcEnable(); + void UdcDisable(); + TInt SetupUdcInterrupt(); + void ReleaseUdcInterrupt(); + void UdcInterruptService(); + void EndpointIntService(TInt aEndpoint); + TInt ResetIntService(); + void SuspendIntService(); + void ResumeIntService(); + void SofIntService(); + static void UdcIsr(TAny* aPtr); + static TInt UsbClientConnectorCallback(TAny* aPtr); + // endpoint zero + void Ep0IntService(); + void Ep0ReadSetupPkt(); + void Ep0Receive(); + void Ep0Transmit(); + void Ep0EndXfer(); + void Ep0Cancel(); + void Ep0PrematureStatusOut(); + void Ep0StatusIn(); + void Ep0NextState(TEp0State aNextState); + // endpoint n with n != 0 + void BulkTransmit(TInt aEndpoint); + void BulkReceive(TInt aEndpoint); + void BulkReadRxFifo(TInt aEndpoint); + void IsoTransmit(TInt aEndpoint); + void IsoReceive(TInt aEndpoint); + void IsoReadRxFifo(TInt aEndpoint); + void IntTransmit(TInt aEndpoint); + void RxComplete(TEndpoint* aEndpoint); + void StopRxTimer(TEndpoint* aEndpoint); + +private: + // general + TBool iSoftwareConnectable; + TBool iCableDetectable; + TBool iCableConnected; + TBool iBusIsPowered; + TBool iInitialized; + TInt (*iUsbClientConnectorCallback)(TAny *); + NaviEngineAssp* iAssp; + // endpoint zero + TBool iEp0Configured; + TEp0State iEp0State; + // endpoints n + TEndpoint iEndpoints[KUsbTotalEndpoints]; // for how this is indexed, see top of pa_usbc.cpp + }; + + +#endif // __PA_USBC_H__ diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/pci/allocator.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/pci/allocator.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,284 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include "allocator.h" +#include + +TAddressAllocator::TAddressAllocator(TLinAddr aMaxSize) + :iMaxSize(aMaxSize) + { + TInt r = iRangeList.Append(TRange(0, iMaxSize, EFalse)); + __NK_ASSERT_ALWAYS(KErrNone==r); + + _LIT(KAllocatorMutex, "PCIAllocatorMutex"); + r = Kern::MutexCreate(iMutex, KAllocatorMutex, KMutexOrdGeneral0); + __NK_ASSERT_ALWAYS(KErrNone==r); + } + +TAddressAllocator::~TAddressAllocator() + { + __NK_ASSERT_DEBUG(iRangeList.Count()==1); + iRangeList.Reset(); + iMutex->Close(NULL); + iMutex=NULL; + } + +/** +@return Indicates if alloc succeeded +@param aAddress This will be set to the starting address of the range if allocation succeeded. +@param aSize Size of memory range required in bytes. This must be a power of 2. +*/ +TInt TAddressAllocator::Allocate(TLinAddr& aAddress, TLinAddr aSize) + { + //check size alignment + __NK_ASSERT_ALWAYS( (aSize & (aSize - 1)) == 0 ); //assert aSize is power of 2. + TInt r = KErrNotFound; + + NKern::ThreadEnterCS(); + Kern::MutexWait(*iMutex); + + const TInt count = iRangeList.Count(); + for(TInt i = 0; i < count; ++i) + { + TRange& range(iRangeList[i]); + if(range.iAllocated == EFalse) + { + //amount which must be added to start address to align to aSize + //(aSize must be a power of 2) + const TLinAddr alignedOffset = (-range.iStart) & (aSize - 1); + + if((alignedOffset + aSize) <= range.iLength) + { + const TLinAddr alignedStart = range.iStart + alignedOffset; + DoAllocate(alignedStart, aSize, i); + aAddress = alignedStart; + r = KErrNone; + break; + } + + } + } + __KTRACE_OPT(KPCI, Kern::Printf("TAddressAllocator::Allocate(): Allocated %d (0x%X) bytes at 0x%X", + aSize, aSize, aAddress)); + Kern::MutexSignal(*iMutex); + NKern::ThreadLeaveCS(); + return r; + } + +/** +Mark region as allocated, with the assumption that region is unallocated. + +@param aAddress The start address requested for new region +@param aSize Length of new region +@param aIndex Position to modify in iRangeList +*/ +void TAddressAllocator::DoAllocate(TLinAddr aAddress, TLinAddr aSize, TInt aIndex) + { + __NK_ASSERT_DEBUG(InvariantCheck()); + //check that new region will lie within existing range + __NK_ASSERT_ALWAYS( + (aAddress >= iRangeList[aIndex].iStart) && + ((aAddress + aSize) <= (iRangeList[aIndex].End() + 1)) + ); + + //allocating at start of unallocated region + if(iRangeList[aIndex].iStart == aAddress) + { + //will there be space left at end of region? + if((iRangeList[aIndex].iLength - aSize) > 0) + { + const TRange newFreeRange(iRangeList[aIndex].iStart + aSize, iRangeList[aIndex].iLength - aSize, EFalse); + const TInt r = iRangeList.Insert(newFreeRange, aIndex + 1); + __NK_ASSERT_ALWAYS(KErrNone == r); + + iRangeList[aIndex].iLength = aSize; + } + + iRangeList[aIndex].iAllocated = ETrue; + } + else + { + //allocating from middle of an unallocated region + const TRange newAllocRange(aAddress, aSize, ETrue); + TInt r = iRangeList.Insert(newAllocRange, aIndex + 1); + __NK_ASSERT_ALWAYS(KErrNone == r); + + //is there an unallocated gap after the newly allocated range? + TLinAddr diff = iRangeList[aIndex].End() - newAllocRange.End(); + if( diff > 0 ) + { + const TRange newFreeRange(newAllocRange.End() + 1, diff, EFalse); + r=iRangeList.Insert(newFreeRange, aIndex + 2); + __NK_ASSERT_ALWAYS(KErrNone == r); + } + + iRangeList[aIndex].iLength = aAddress - iRangeList[aIndex].iStart; + } + //calculate invariant: run through array to check that ranges are contiguous + __NK_ASSERT_DEBUG(InvariantCheck()); + } + +#if defined (_DEBUG) +void TAddressAllocator::Print() + { + __KTRACE_OPT(KPCI, Kern::Printf("TAddressAllocator::Print(): Printing ranges")); + const TInt count = iRangeList.Count(); + for(TInt i=0; i0); + __NK_ASSERT_ALWAYS(iRangeList[0].iStart==0); + __NK_ASSERT_ALWAYS(iRangeList[count-1].End()==iMaxSize-1); + + for(TInt i=1; i0); + + //check that free spaces are always consolidated + if(!prev.iAllocated) + { + __NK_ASSERT_ALWAYS(curr.iAllocated); + } + } + return ETrue; + } +#endif + +TInt TAddressAllocator::TRange::OrderByStart(const TRange& aKeyRange, const TRange& aRange) + { + if(aKeyRange.iStart > aRange.iStart) + return 1; + else if(aKeyRange.iStart < aRange.iStart) + return -1; + else + return 0; + } + +/** +Make a region of PCI memory available again. + +@param aAddress Start address of an allocated PCI range to deallocate. +@return + - KErrNone If the region was deallocated + - KErrNotFound if aAddress is not the beginning of a previously + allocated range. +*/ +TInt TAddressAllocator::DeAllocate(TLinAddr aAddress) + { + NKern::ThreadEnterCS(); + Kern::MutexWait(*iMutex); + + TInt r=KErrNone; + + TRange key(aAddress, 0, EFalse); + TLinearOrder startOrder(TRange::OrderByStart); + TInt index = iRangeList.FindInOrder(key, startOrder); + + if(index==KErrNotFound || (!iRangeList[index].iAllocated)) + { + r=KErrNotFound; + } + else + { + Remove(index); + } + + Kern::MutexSignal(*iMutex); + NKern::ThreadLeaveCS(); + return r; + } + +/** +Remove the allocated region and adjust remaining regions +to consolidate free space. +*/ +void TAddressAllocator::Remove(TInt aIndex) + { + __KTRACE_OPT(KPCI, Kern::Printf("TAddressAllocator::Remove(): Removing %d (0x%X) bytes at 0x%X", + iRangeList[aIndex].iLength, iRangeList[aIndex].iLength, iRangeList[aIndex].iStart)); + __NK_ASSERT_DEBUG(InvariantCheck()); + const TInt count = iRangeList.Count(); + //range is above an unallocated range + if(aIndex > 0 && (!iRangeList[aIndex - 1].iAllocated) ) + { + //range is below unallocated range + if(aIndex < (count - 1) && !(iRangeList[aIndex + 1].iAllocated)) + { + iRangeList[aIndex - 1].iLength = iRangeList[aIndex + 1].End() + 1 -iRangeList[aIndex - 1].iStart; + iRangeList.Remove(aIndex); + iRangeList.Remove(aIndex); +#ifdef _DEBUG + //The PCI kernel extension contains several persistent dynamic arrays and by default these RArrays + //do not free heap for every item that is removed. In order to ensure that kernel heap checking + //succeeds Compress() calls are needed to force this excess memory to be freed. This calls are only + //made in UDEB builds only as KHEAP checks are only performed in UDEB mode. + iRangeList.Compress(); +#endif + } + else + { + iRangeList[aIndex - 1].iLength = iRangeList[aIndex].End() + 1 - iRangeList[aIndex - 1].iStart; + iRangeList.Remove(aIndex); +#ifdef _DEBUG + //The PCI kernel extension contains several persistent dynamic arrays and by default these RArrays + //do not free heap for every item that is removed. In order to ensure that kernel heap checking + //succeeds Compress() calls are needed to force this excess memory to be freed. This calls are only + //made in UDEB builds only as KHEAP checks are only performed in UDEB mode. + iRangeList.Compress(); +#endif + } + } + //range is above allocated range + else + { + //range is below unallocated range + if(aIndex < (count - 1) && !(iRangeList[aIndex + 1].iAllocated)) + { + iRangeList[aIndex].iAllocated=EFalse; + iRangeList[aIndex].iLength=iRangeList[aIndex + 1].End() + 1 - iRangeList[aIndex].iStart; + iRangeList.Remove(aIndex + 1); +#ifdef _DEBUG + //The PCI kernel extension contains several persistent dynamic arrays and by default these RArrays + //do not free heap for every item that is removed. In order to ensure that kernel heap checking + //succeeds Compress() calls are needed to force this excess memory to be freed. This calls are only + //made in UDEB builds only as KHEAP checks are only performed in UDEB mode. + iRangeList.Compress(); +#endif + } + else + { + iRangeList[aIndex].iAllocated = EFalse; + } + } + //calculate invariant: run through array to check that ranges are contiguous + __NK_ASSERT_DEBUG(InvariantCheck()); + } + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/pci/allocator.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/pci/allocator.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,72 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#ifndef ALLOCATOR_H +#define ALLOCATOR_H + +#include + +class DMutex; + +/** +Keeps track of what address ranges are available +Address ranges will be size aligned. ie. 4k range will be aligned to 4k +boundary, 1k range will be aligned to 1k boundary +*/ +class TAddressAllocator + { +public: + TAddressAllocator(TLinAddr aMaxSize); + ~TAddressAllocator(); + TInt Allocate(TLinAddr& aAddress, TLinAddr aSize); + TInt DeAllocate(TLinAddr aAddress); +private: + /** + A contiguous address region. + */ + struct TRange + { + TRange(TLinAddr aStart, TLinAddr aLength, TBool aAllocated) + :iAllocated(aAllocated), iStart(aStart), iLength(aLength) + { + } + inline TLinAddr End() const + { return iStart+iLength-1;} + + static TInt OrderByStart(const TRange& aKeyRange, const TRange& aRange); + + TBool iAllocated; + TLinAddr iStart; + TLinAddr iLength; + }; + + void DoAllocate(TLinAddr aAddress, TLinAddr aSize, TInt aIndex); + void Remove(TInt aIndex); +#if defined (_DEBUG) + void Print(); + TBool InvariantCheck(); +#endif + + + const TLinAddr iMaxSize; + RArray iRangeList; //a list of contiguous, non-overlapping address regions. + DMutex* iMutex; + }; + +#endif //ALLOCATOR_H diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/pci/chunkman.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/pci/chunkman.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,456 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include "pci-ne.h" +#include "../naviengine_pci.h" +#include +#include + +// +// TChunkManager +// + +TChunkManager::TChunkRecord::TChunkRecord(DPlatChunkHw* aChunk, TInt32 aSize) + :iChunk(aChunk), iSize(aSize) + { + } + +/** +A utitlity function so that we can find pci chunks structs in iChunks array +*/ +TBool TChunkManager::TChunkRecord::ChunkComparator(const TChunkRecord& aKeyRecord, const TChunkRecord& aRecord) + { + return (aKeyRecord.iChunk==aRecord.iChunk); + } + +TChunkManager::TChunkManager(TMappingManager& aMapMan) + :iMapMan(aMapMan), iChunks(), iSharedChunks(), iMutex(NULL) + { + _LIT(KChunkManMutex, "PCI_Chunk_Man_Mutex"); + TInt r = Kern::MutexCreate(iMutex, KChunkManMutex, KMutexOrdGeneral2); + __NK_ASSERT_ALWAYS(KErrNone==r); + } + +TChunkManager::~TChunkManager() + { + iChunks.Reset(); + iSharedChunks.Reset(); + iMutex->Close(NULL); + } + + +/** +@param aChunk a NULL pointer. Will be set to new chunk on success. +@param aPciAddress On success will be set to address of chunk buffer in PCI address space +@param aSize The size of the chunk to allocate +@return An errror code. + - KErrNotFound All of Bridges BARS have been used up. +*/ +TInt TChunkManager::AddChunk(DPlatChunkHw*& aChunk, TInt& aSize, TUint aAttributes, TUint32& aPciAddress) + { + NKern::ThreadEnterCS(); + Kern::MutexWait(*iMutex); + + DPlatChunkHw* chunk=NULL; + TUint32 pciAddress=NULL; + TInt32 size=aSize; + + TInt r=DoAddChunk(chunk, aSize, aAttributes, pciAddress); + if(r==KErrNone) + { + aChunk=chunk; + aPciAddress=pciAddress; + aSize=size; + } + + Kern::MutexSignal(*iMutex); + NKern::ThreadLeaveCS(); + + return r; + } + +/** +@param aPciAddress On success will be set to address of chunk buffer in PCI address space +@param aSize The size of the chunk to allocate +@return An errror code. + - KErrNotFound All of Bridges BARS have been used up. +*/ +TInt TChunkManager::DoAddChunk(DPlatChunkHw*& aChunk, TInt aSize, TUint aAttributes, TUint32& aPciAddress) + { + + #ifdef _DEBUG + __ASSERT_CRITICAL; + __ASSERT_MUTEX(iMutex); + #endif + + TInt requestedSize=Clp2(aSize); + //Although the client has specified aSize, the actual chunk we get may be larger as it will be rounded to a page size. + //CreateChunk may adjust its size parameter to be the actual size allocated. + TInt r = CreateChunk(aChunk, aSize, aAttributes); + if(r!=KErrNone) + return r; + + const TUint32 physicalAddress=aChunk->PhysicalAddress(); + + //even if physical memory block was 4K, it is ok to have a smaller + //pci mapping as long as its size is power of 2 + TInt mapSize = Min(requestedSize, aSize); + r = iMapMan.CreateMapping(physicalAddress, mapSize, aPciAddress); + + //no point having chunk if no mapping in pci space. + if(r!=KErrNone) + { + const TInt ret=DeleteChunk(aChunk, aSize); + __NK_ASSERT_ALWAYS(KErrNone==ret); + return r; + } + + //remember the actual size of memory allocated to chunk + const TChunkRecord newRecord(aChunk, aSize); + r = iChunks.Append(newRecord); + + // delete chunk if a record of it can't be kept. + if(r!=KErrNone) + { + const TInt ret=DeleteChunk(aChunk, aSize); + __NK_ASSERT_ALWAYS(KErrNone==ret); + return r; + } + + return r; + } + +/** +Creates a chunk of specified size, but rounded up to at least a page. +@param aChunk On success will be set to the new chunk. +@param aSize Size of chunk required, on return will have modfied if size was rounded up. +@param aAttributes A bit mask of TMappingAttributes values. +@return + - KErrNone + - KErrNoMemory +*/ +TInt TChunkManager::CreateChunk(DPlatChunkHw*& aChunk, TInt& aSize, TUint aAttributes) + { + aSize = Kern::RoundToPageSize(aSize); + aSize = Clp2(aSize); + + NKern::ThreadEnterCS(); + + TPhysAddr physicalAddress=NULL; + TInt r=Epoc::AllocPhysicalRam(aSize, physicalAddress, Log2(aSize)); + if(r!=KErrNone) + { + __KTRACE_OPT(KPCI, Kern::Printf("TChunkManager::CreateChunk(): Phys memory alloc failed with error=%d, size=%d (0x%X)", r, aSize, aSize)); + NKern::ThreadLeaveCS(); + return r; + } + + r = DPlatChunkHw::New(aChunk,physicalAddress, aSize, aAttributes); + if(r!=KErrNone) + { + __KTRACE_OPT(KPCI, Kern::Printf("TChunkManager::CreateChunk(): Chunk creation failed with status %d, phys addr=0x%08x, size=%d (0x%X)", r, physicalAddress, aSize, aSize)); + const TInt ret=Epoc::FreePhysicalRam(physicalAddress, aSize); + __NK_ASSERT_ALWAYS(KErrNone==ret); + NKern::ThreadLeaveCS(); + return r; + } + + NKern::ThreadLeaveCS(); + + __KTRACE_OPT(KPCI, Kern::Printf("TChunkManager::CreateChunk(): Chunk created at 0x%08x, phys addr=0x%08x, size=%d (0x%X)", aChunk, physicalAddress, aSize, aSize)); + return r; + } + + +/** +Delete and remove PCI mapping for a chunk previously created by this class + +@param aChunk pointer to a chunk to remove. +@return + - KErrNone + - KErrNotFound aChunk was not allocated by this class +*/ +TInt TChunkManager::RemoveChunk(DPlatChunkHw* aChunk) + { + NKern::ThreadEnterCS(); + Kern::MutexWait(*iMutex); + + __KTRACE_OPT(KPCI, Kern::Printf("TChunkManager::RemoveChunk(): Removing chunk at 0x%08X", aChunk)); + const TChunkRecord key(aChunk, 0); + TInt index=iChunks.Find(key, TIdentityRelation(TChunkRecord::ChunkComparator) ); + TInt r=KErrNone; + if(index!=KErrNotFound) + { + r = iMapMan.RemoveMapping(iChunks[index].iChunk->PhysicalAddress() ); + __NK_ASSERT_ALWAYS(KErrNone==r); + r = DeleteChunk(iChunks[index].iChunk, iChunks[index].iSize); + __NK_ASSERT_ALWAYS(r==KErrNone); + + iChunks.Remove(index); +#ifdef _DEBUG + //free space when entry removed + iChunks.Compress(); +#endif + } + else + r=index; + + Kern::MutexSignal(*iMutex); + NKern::ThreadLeaveCS(); + + return r; + } + +/** +Delete chunk and remove aSize of physical RAM +*/ +TInt TChunkManager::DeleteChunk(DPlatChunkHw* aChunk, TInt aSize) + { + const TPhysAddr address = aChunk->PhysicalAddress(); + NKern::ThreadEnterCS(); + __KTRACE_OPT(KPCI, Kern::Printf("TChunkManager::DeleteChunk(): Freeing physical RAM: %d (0x%X) bytes at 0x%X ", aSize, aSize, address)); + Kern::SafeClose(reinterpret_cast(aChunk), NULL); + TInt r=Epoc::FreePhysicalRam(address,aSize); + NKern::ThreadLeaveCS(); + return r; + } + + +// +// Shared Chunk methods +// + +TChunkManager::TSCRecord::TSCRecord(DChunk* aChunk, TUint32 aPhysAddr) + :iChunk(aChunk), iPhysAddr(aPhysAddr), iMapped(EFalse), iSize(0) + { + } + + +TBool TChunkManager::TSCRecord::ChunkComparator(const TSCRecord& aKeyRecord, const TSCRecord& aRecord) + { + return (aKeyRecord.iPhysAddr==aRecord.iPhysAddr); + } + +TInt TChunkManager::AddChunk(DChunk*& aChunk, TChunkCreateInfo& aAttributes, TUint aOffset, TUint& aSize, TUint32& aPciAddress) + { + NKern::ThreadEnterCS(); + Kern::MutexWait(*iMutex); + + DChunk* chunk=NULL; + TUint32 pciAddress; + + TInt r=DoAddChunk(chunk, aAttributes, aOffset, aSize, pciAddress); + if(r==KErrNone) + { + aChunk=chunk; + aPciAddress=pciAddress; + } + + Kern::MutexSignal(*iMutex); + NKern::ThreadLeaveCS(); + + return r; + } + +void TChunkManager::RemoveChunk(TUint32 aPhysicalAddress) + { + NKern::ThreadEnterCS(); + Kern::MutexWait(*iMutex); + + const TSCRecord key(NULL, aPhysicalAddress); + + TInt index=iSharedChunks.Find(key, TIdentityRelation(TSCRecord::ChunkComparator) ); + __NK_ASSERT_ALWAYS(index!=KErrNotFound); + + TSCRecord& record(iSharedChunks[index]); + __NK_ASSERT_DEBUG(record.iPhysAddr==aPhysicalAddress); + + // We will always have to free RAM + const TInt size=record.iSize; + __KTRACE_OPT(KPCI, Kern::Printf("TChunkManager::RemoveChunk(TUint32) Freeing physical RAM: %d (0x%X) bytes at 0x%X ", size, size, aPhysicalAddress)); + NKern::ThreadEnterCS(); + TInt r = Epoc::FreePhysicalRam(aPhysicalAddress, size); + NKern::ThreadLeaveCS(); + __NK_ASSERT_ALWAYS(KErrNone==r); + + if(record.iMapped) + { + __KTRACE_OPT(KPCI, + Kern::Printf("TChunkManager::RemoveChunk(TUint32) Removing PCI mapping for RAM: %d (0x%X) bytes at 0x%X ", + size, size, record.iPhysAddr)); + + TInt r=iMapMan.RemoveMapping(record.iPhysAddr); + __NK_ASSERT_ALWAYS(KErrNone==r); + } + else + { + __KTRACE_OPT(KPCI, Kern::Printf("TChunkManager::RemoveChunk(TUint32) No PCI mapping for memory")); + } + + iSharedChunks.Remove(index); +#ifdef _DEBUG + //free space when entry removed + iSharedChunks.Compress(); +#endif + + Kern::MutexSignal(*iMutex); + NKern::ThreadLeaveCS(); + } + +TInt TChunkManager::DoAddChunk(DChunk*& aChunk, TChunkCreateInfo& aAttributes, TUint aOffset, TUint& aSize, TUint32& aPciAddress) + { + TInt r = iSharedChunks.Append(TSCRecord(NULL, NULL)); + if(r!=KErrNone) + { + return r; + } + + const TInt count = iSharedChunks.Count(); + TSCRecord& newRecord(iSharedChunks[count-1]); + //Although the client has specified aSize, the actual chunk we get may be larger as it will be rounded to a page size. + //CreateChunk may adjust its size parameter to be the actual size allocated. + r = CreateChunk(aChunk, aAttributes, aOffset, aSize, newRecord); + if(r!=KErrNone) + { + //If newRecord is not populated we must remove it. + //If it has been populated, the chunk record will + //be removed by the chunk's cleanup DFC and we must leave + //it alone. + if(newRecord.iChunk==NULL) + { + iSharedChunks.Remove(count-1); +#ifdef _DEBUG + //free space when entry removed + iSharedChunks.Compress(); +#endif + } + + return r; + } + + //map all of the commited memory, which may exceed what the client requested + //The minumum memory allocation is 4k + //And memory must also be mapped in powers of 2 eg. A request for 11k would create + //and map 16K + + + //need CS since if we succeed in creating a mapping we + //must be allowed to toggle the iMapped flag in the record array. + NKern::ThreadEnterCS(); + TInt size=aSize; + r = iMapMan.CreateMapping(newRecord.iPhysAddr, size, aPciAddress); + + //no point having chunk if no mapping in pci space. + if(r!=KErrNone) + { + //chunk will proceed to cleanup memory only + TBool destructionPending=Kern::ChunkClose(aChunk); + NKern::ThreadLeaveCS(); + __NK_ASSERT_ALWAYS(destructionPending); + return r; + } + newRecord.iMapped=ETrue; + NKern::ThreadLeaveCS(); + + __NK_ASSERT_ALWAYS(r==KErrNone); //we reserved space for this + + return r; + } + +TInt TChunkManager::CreateChunk(DChunk*& aChunk, TChunkCreateInfo& aAttributes, TUint aOffset, TUint& aSize, TSCRecord& aRecord) + { + //natuarally align aSize. + const TInt size=Clp2(aSize); + const TInt align=Log2(size); + + TPhysAddr physicalAddress=NULL; + + NKern::ThreadEnterCS(); + TInt r = Epoc::AllocPhysicalRam(size, physicalAddress, align); + if(r != KErrNone) + { + __KTRACE_OPT(KPCI, Kern::Printf("TChunkManager::CreateChunk(DChunk*): Phys memory alloc failed with error=%d, size=%d (0x%X)", r, size, size)); + NKern::ThreadLeaveCS(); + return r; + } + + //now that we know the physical address of our memory + //we can create the cleanup object + TNaviEngineChunkCleanup* cleanup= new TNaviEngineChunkCleanup(*this, physicalAddress); + if(cleanup == NULL) + { + //free physical ram + r = Epoc::FreePhysicalRam(physicalAddress, size); + __NK_ASSERT_ALWAYS(KErrNone==r); + NKern::ThreadLeaveCS(); + return KErrNoMemory; + } + + //Since we are mapping in memory we alloc'd + //the chunk is not responsible for freeing it. + aAttributes.iOwnsMemory=EFalse; + + //ensure that max size is large enough to contain the rounded physical block plus specified guard offsets + //at each end + aAttributes.iMaxSize=Max(aAttributes.iMaxSize, size+(2*aOffset)); + + aAttributes.iDestroyedDfc = cleanup; + + TLinAddr kernAddr; + TUint32 attribs; + r=Kern::ChunkCreate(aAttributes, aChunk, kernAddr, attribs); + if(r != KErrNone) + { + //free physical ram + TInt err = Epoc::FreePhysicalRam(physicalAddress, size); + __NK_ASSERT_ALWAYS(KErrNone==err); + + delete cleanup; + NKern::ThreadLeaveCS(); + return r; + } + //At this point, the cleanup object will look after its own destruction + //when the chunk is closed + cleanup=NULL; + + //these will be requird in order to free physical memory if we have to close the chunk + aRecord.iPhysAddr=physicalAddress; + aRecord.iChunk=aChunk; + aRecord.iSize=size; + + r=Kern::ChunkCommitPhysical(aChunk, aOffset, size, physicalAddress); + + if(r!=KErrNone) + { + TBool destructionPending=Kern::ChunkClose(aChunk); + __NK_ASSERT_ALWAYS(destructionPending); + NKern::ThreadLeaveCS(); + return r; + } + + //report back size commited + aSize=size; + __KTRACE_OPT(KPCI, Kern::Printf("TChunkManager::CreateChunk(DChunk*): Chunk created at 0x%08x, phys addr=0x%08x, size=%d (0x%X)", + aChunk, physicalAddress, aSize, aSize)); + + NKern::ThreadLeaveCS(); + return r; + } + + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/pci/chunkman.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/pci/chunkman.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,96 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#ifndef __CHUNKMAN_H__ +#define __CHUNKMAN_H__ + +#include + +class TAddressAllocator; +class DPlatChunkHw; +class DChunk; +class TChunkCreateInfo; +class DMutex; + + +/** +Responsible for allocating and deallocating chunks which +are accessible from the PCI bus. + +At present there can be only 1 chunk associated with each BAR. +It would be possible to access more than one chunk per BAR, providing +the chunks were physically contiguous with each other, +*/ +class TChunkManager + { +public: + TChunkManager(TMappingManager& aMapMan); + ~TChunkManager(); + TInt AddChunk(DPlatChunkHw*& aChunk, TInt& aSize, TUint aAttributes, TUint32& aPciAddress); + TInt RemoveChunk(DPlatChunkHw* aChunk); + + TInt AddChunk(DChunk*& aChunk, TChunkCreateInfo& aAttributes, TUint aOffset, TUint& aSize, TUint32& aPciAddress); + void RemoveChunk(TUint32 aPhysicalAddress); + +private: + /** + Used to keep a record of an allocated chunk + */ + struct TChunkRecord + { + TChunkRecord(DPlatChunkHw* aChunk, TInt32 aSize); + static TBool ChunkComparator(const TChunkRecord& aKeyRecord, const TChunkRecord& aRecord); + + DPlatChunkHw* iChunk; + // DPlayChunkHw do not know the size which has been allocated to them. + TInt32 iSize; + }; + + /** + Used to keep a record of a shared chunk + */ + struct TSCRecord + { + TSCRecord(DChunk* aChunk, TUint32 aPhysAddr); + static TBool ChunkComparator(const TSCRecord& aKeyRecord, const TSCRecord& aRecord); + + DChunk* iChunk; + TUint32 iPhysAddr; //we need to remember this as it allows PCI mapping to be freed + TBool iMapped; //says whether this chunk is mapped into PCI + TInt32 iSize; + }; + + TInt DoAddChunk(DPlatChunkHw*& aChunk, TInt aSize, TUint aAttributes, TUint32& aPciAddress); + TInt CreateChunk(DPlatChunkHw*& aChunk, TInt& aSize, TUint aAttributes); + TInt DeleteChunk(DPlatChunkHw* aChunk, TInt aSize); + + TInt DoAddChunk(DChunk*& aChunk, TChunkCreateInfo& aAttributes, TUint aOffset, TUint& aSize, TUint32& aPciAddress); + TInt CreateChunk(DChunk*& aChunk, TChunkCreateInfo& aAttributes, TUint aOffset, TUint& aSize, TSCRecord& aRecord); + + typedef DPlatChunkHw* DPlatChunkHwP; + + TMappingManager& iMapMan; + + RArray iChunks; + RArray iSharedChunks; + DMutex* iMutex; + + + }; +#endif // __CHUNKMAN_H__ diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/pci/mapman.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/pci/mapman.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,289 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include "pci-ne.h" +#include "../naviengine_pci.h" +#include +#include + +// +// Global helper functions +// + + +/** +Integer log base 2 for power of 2 +*/ +TUint32 Log2(TUint32 aNumber) + { + __NK_ASSERT_ALWAYS(aNumber>0); + __NK_ASSERT_DEBUG((aNumber&(aNumber-1))==0); //assert that size is power of 2 + const TUint32 b[] = {0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000}; + + TUint32 r = (aNumber & b[0]) != 0; + r |= ((aNumber & b[4]) != 0) << 4; + r |= ((aNumber & b[3]) != 0) << 3; + r |= ((aNumber & b[2]) != 0) << 2; + r |= ((aNumber & b[1]) != 0) << 1; + return r; + } + +/** +Ceiling power 2. Round up aNumber to the next power of 2. +*/ +TUint32 Clp2(TUint32 aNumber) + { + aNumber -= 1; + aNumber |= aNumber >> 1; + aNumber |= aNumber >> 2; + aNumber |= aNumber >> 4; + aNumber |= aNumber >> 8; + aNumber |= aNumber >> 16; + return aNumber+1; + } + + +// +// TMappingManager +// + +/** +Just make sure members are zeroed +*/ +TMappingManager::TMapping::TMapping() + :iPciAddr(NULL), iPhysAddr(NULL), iUsed(EFalse) + {} + +/** +A compare function so that we can find used/unused mappings in RArray. +*/ +TBool TMappingManager::TMapping::UsedCompare(const TMapping& aKeyMapping, const TMapping& aMapping) + { + return aKeyMapping.iUsed==aMapping.iUsed; + } + +/** +A compare function so that we can find mappings to specific phys addr in RArray. +*/ +TBool TMappingManager::TMapping::PhysAddrCompare(const TUint32* aPhysAddr, const TMapping& aMapping) + { + return *aPhysAddr==aMapping.iPhysAddr; + } + +TBool TMappingManager::TMapping::ContainsPhysical(const TUint32* aPhysAddr, const TMapping& aMapping) + { + return aMapping.iUsed && Rng(aMapping.iPhysAddr, *aPhysAddr, aMapping.iPhysAddr+aMapping.iSize-1); + } + +TBool TMappingManager::TMapping::ContainsPci(const TUint32* aPciAddr, const TMapping& aMapping) + { + return aMapping.iUsed && Rng(aMapping.iPciAddr, *aPciAddr, aMapping.iPciAddr+aMapping.iSize-1); + } + +TUint32 TMappingManager::TMapping::PciAddress(TUint32 aPhysAddress) + { + __NK_ASSERT_ALWAYS(Rng(iPhysAddr, aPhysAddress, iPhysAddr+iSize-1)); + return iPciAddr+(aPhysAddress-iPhysAddr); + } + +TUint32 TMappingManager::TMapping::PhysAddress(TUint32 aPciAddress) + { + __NK_ASSERT_ALWAYS(Rng(iPciAddr, aPciAddress, iPciAddr+iSize-1)); + return iPhysAddr+(aPciAddress-iPciAddr); + } + +TMappingManager::TMappingManager(TInt aNumOfBars, TAddressAllocator& aAllocator, TUint32 aBaseAddress) + : iAllocator(aAllocator), iNumOfBars(aNumOfBars), iBaseAddress(aBaseAddress), iMappings(iNumOfBars), iMutex(NULL) + { + _LIT(KChunkManMutex, "PCI_Map_Man_Mutex"); + TInt r=Kern::MutexCreate(iMutex, KChunkManMutex, KMutexOrdGeneral1); + __NK_ASSERT_ALWAYS(KErrNone==r); + + TMapping emptyRecord; + for(TInt i=0; iClose(NULL); + iMappings.Reset(); + } + +/** +Obtain a block of memory from PCI memory space, and map it to the supplied aPhysicalAddress. +@param aPhysicalAddress The system memory address to which window points. +Must be naturally aligned in accord with aSize. Eg. a 1MB memory block must be alligned to a 1MB boundary. +@param aSize Size of mapping. Must be a power of 2 and greater than 1KB. +@param On return Will be set to the PCI address of the window. +@return + - KErrNone Success + - KErrNotSupported aPhysicalAddress was not aligned correctly or aSize was not a power of 2 +*/ +TInt TMappingManager::CreateMapping(TUint32 aPhysicalAddress, TInt aSize, TUint32& aPciAddress) + { + NKern::ThreadEnterCS(); + Kern::MutexWait(*iMutex); + + if(aSize=KMinOutboundWindow); //assert that size is greater than minimum window + __NK_ASSERT_ALWAYS((aSize&(aSize-1))==0); //assert that size is power of 2 + + TInt r=KErrNone; + const TMapping unusedKey; + const TInt barIndex = iMappings.Find(unusedKey, TIdentityRelation(TMapping::UsedCompare)); + if(KErrNotFound==barIndex) + { + r=barIndex; + goto End; + } + + //ensure that aPhysicalAddress is aligned correctly for the + //window size + if(aPhysicalAddress&(aSize-1)) + { + r=KErrNotSupported; + goto End; + } + + r = iAllocator.Allocate(aPciAddress, aSize); + if(r!=KErrNone) + { + goto End; + } + + DoCreateMapping(barIndex, aPhysicalAddress, aSize, aPciAddress); + +End: + Kern::MutexSignal(*iMutex); + NKern::ThreadLeaveCS(); + return r; + } + +void TMappingManager::DoCreateMapping(TInt aBarIndex, TUint32 aPhysicalAddress, TInt& aSize, TUint32& aPciAddress) + { + __KTRACE_OPT(KPCI, Kern::Printf("Create PCI window mapping: phys=0x%08x, pci=0x%08x, size=0x%08x, BarIndex=%d ", aPhysicalAddress, aPciAddress, aSize, aBarIndex)); + //The bar mask field in the + //ACR determines how many of the upper bits + //of an accessed PCI address should be converted + //before being forwarded to AHB. + //This is equivalent to 32-log2(size) + const TUint32 log2Size=Log2(aSize); + const TUint32 acrBarMask = ((32-log2Size)<<4)&KHmAcr_BarMask; + const TUint32 acrValue = aPhysicalAddress|acrBarMask|KHtAcr_P2Ace; + const TUint32 barValue = aPciAddress; + __KTRACE_OPT(KPCI, Kern::Printf(" calculated bar mask = 0x%08x", acrBarMask)); + __KTRACE_OPT(KPCI, Kern::Printf(" writing acrValue = 0x%08x @ os 0x%08x", acrValue, KHoAcr[aBarIndex])); + __KTRACE_OPT(KPCI, Kern::Printf(" writing barValue = 0x%08x @ os 0x%08x", barValue, KHoBar[aBarIndex])); + + AsspRegister::Write32(iBaseAddress+KHoAcr[aBarIndex],acrValue); + AsspRegister::Write32(iBaseAddress+KHoBar[aBarIndex],barValue); + + //set bit for this bar in the bar-enable register + AsspRegister::Modify32(iBaseAddress+KHoBarEnable, NULL, (1< + +//helper maths functions +TUint32 Clp2(TUint32 aNumber); +TUint32 Log2(TUint32 aNumber); + +class TAddressAllocator; +class DMutex; + +/** +Responsible for creating outbound mappings so that +PCI peripherals can access system memory. +*/ +class TMappingManager + { +public: + TMappingManager(TInt aNumOfBars, TAddressAllocator& aAllocator, TUint32 aBaseAddress); + ~TMappingManager(); + TInt CreateMapping(TUint32 aPhysicalAddress, TInt aSize, TUint32& aPciAddress); + TInt RemoveMapping(TUint32 aPhysicalAddress); + + TInt GetPciAddress(TUint32 aPhysicalAddress, TUint32& aPciAddress); + TInt GetPhysicalAddress(TUint32 aPciAddress, TUint32& aPhysicalAddress); + +private: + /** + Associates BAR with an allocated PCI address + */ + struct TMapping + { + TMapping(); + static TBool UsedCompare(const TMapping& aKeyMapping, const TMapping& aMapping); + static TBool PhysAddrCompare(const TUint32*, const TMapping& aMapping); + static TBool ContainsPhysical(const TUint32*, const TMapping& aMapping); + static TBool ContainsPci(const TUint32*, const TMapping& aMapping); + + inline TUint32 PciAddress(TUint32 aPhysAddress); + inline TUint32 PhysAddress(TUint32 aPciAddress); + + TUint32 iPciAddr; + TUint32 iPhysAddr; + TUint32 iSize; + TBool iUsed; + }; + + void DoCreateMapping(TInt aBarIndex, TUint32 aPhysicalAddress, TInt& aSize, TUint32& aPciAddress); + + TAddressAllocator& iAllocator; + const TInt iNumOfBars; + const TUint32 iBaseAddress; + + RArray iMappings; + DMutex* iMutex; + }; +#endif // __MAPMAN_H__ diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/pci/pci-ne.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/pci/pci-ne.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,773 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include "pci-ne.h" +#include "../naviengine_pci.h" +#include +#include + + +_LIT(KTConfigSpace, "TConfigSpace"); +TConfigSpace::TConfigSpace(TPciFunction& aFunction, DPciBridge& aBridge) + :TAddrSpace(KCfgSpaceSize, KTConfigSpace), iFunction(aFunction), iBridge(aBridge) + { + } + +/** +Read 1 byte from config space. Config space is 256 bytes long +out of range access will fault the kernel. +*/ +EXPORT_C TUint8 TConfigSpace::Read8(TUint32 aOffset) + { + CheckAccess(E1Byte, aOffset); + + return iBridge.ReadConfig8( + iFunction.Bus(), + iFunction.Device(), + iFunction.Function(), + aOffset + ); + } + +EXPORT_C TUint16 TConfigSpace::Read16(TUint32 aOffset) + { + CheckAccess(E2Byte, aOffset); + + return iBridge.ReadConfig16( + iFunction.Bus(), + iFunction.Device(), + iFunction.Function(), + aOffset + ); + } + +EXPORT_C TUint32 TConfigSpace::Read32(TUint32 aOffset) + { + CheckAccess(E4Byte, aOffset); + + return iBridge.ReadConfig32( + iFunction.Bus(), + iFunction.Device(), + iFunction.Function(), + aOffset + ); + } + +EXPORT_C void TConfigSpace::Write8(TUint32 aOffset, TUint8 aValue) + { + CheckAccess(E1Byte, aOffset); + + iBridge.WriteConfig8( + iFunction.Bus(), + iFunction.Device(), + iFunction.Function(), + aOffset, + aValue + ); + } + +EXPORT_C void TConfigSpace::Write16(TUint32 aOffset, TUint16 aValue) + { + CheckAccess(E2Byte, aOffset); + + iBridge.WriteConfig16( + iFunction.Bus(), + iFunction.Device(), + iFunction.Function(), + aOffset, + aValue + ); + } + +EXPORT_C void TConfigSpace::Write32(TUint32 aOffset, TUint32 aValue) + { + CheckAccess(E4Byte, aOffset); + + iBridge.WriteConfig32( + iFunction.Bus(), + iFunction.Device(), + iFunction.Function(), + aOffset, + aValue + ); + } + +EXPORT_C void TConfigSpace::Modify8(TUint32 aOffset, TUint8 aClearMask, TUint8 aSetMask) + { + CheckAccess(E1Byte, aOffset); + + iBridge.ModifyConfig8( + iFunction.Bus(), + iFunction.Device(), + iFunction.Function(), + aOffset, + aClearMask, + aSetMask + ); + } + +EXPORT_C void TConfigSpace::Modify16(TUint32 aOffset, TUint16 aClearMask, TUint16 aSetMask) + { + CheckAccess(E2Byte, aOffset); + + iBridge.ModifyConfig16( + iFunction.Bus(), + iFunction.Device(), + iFunction.Function(), + aOffset, + aClearMask, + aSetMask + ); + } + +EXPORT_C void TConfigSpace::Modify32(TUint32 aOffset, TUint32 aClearMask, TUint32 aSetMask) + { + CheckAccess(E4Byte, aOffset); + + iBridge.ModifyConfig32( + iFunction.Bus(), + iFunction.Device(), + iFunction.Function(), + aOffset, + aClearMask, + aSetMask + ); + } + +DNaviEnginePciBridge::DNaviEnginePciBridge(TUint aBaseAddress, TUint32 aVirtualWindow) + :DPciBridge(), iBaseAddr(aBaseAddress), + iVirtualWindow(aVirtualWindow), + iAllocator(KPciAddressSpaceSize), + iMapMan(KNeBridgeNumberOfBars, iAllocator, iBaseAddr), + iChunkMan(iMapMan), + iVid(AsspRegister::Read16(iBaseAddr+KHoPciVid)), + iDid(AsspRegister::Read16(iBaseAddr+KHoPciDid)) + { + } + +TInt DNaviEnginePciBridge::Initialise() + { + __KTRACE_OPT(KPCI, Kern::Printf("Initialising Naviengine bridge: Base address: %x", iBaseAddr)) ; + InitialiseRegisters(); + return SetupInterrupts(); + } + +DNaviEnginePciBridge::~DNaviEnginePciBridge() + { + } + +/** +Create a DPlatChunkHw which will be accessble to PCI devices under this bridge. + +@param aSize Amount of memory visible from PCI in bytes. +This will be rounded up to the next power of 2 in kilobytes +.eg 1K, 2K, 4K etc. @note The actual amount of memory allocated +will always be a multiple of the page size (4K), but any excess +will not be visible to the PCI bus. +@param aPciAddress On success, will be a PCI address by which the chunk may be accessed +@return + - KErrNone - On Success + - KErrInUse - aChunk was not NULL + - KErrNotFound - All of Bridge's BARS have been used up. Free one with RemoveChunk + - KErrArgument - aSize was less than 1. +*/ +TInt DNaviEnginePciBridge::CreateChunk(DPlatChunkHw*& aChunk, TInt aSize, TUint aAttributes, TUint32& aPciAddress) + { + if(aChunk!=NULL) + return KErrInUse; + if(aSize<1) + return KErrArgument; + + return iChunkMan.AddChunk(aChunk, aSize, aAttributes, aPciAddress); + } + +/** +Create a DChunk which will be accessble to PCI devices under this bridge. + +@param aSize Amount of memory to be allocated to chunk. +This will be rounded up to at least the next power of 2 in kilobytes +.eg 1K, 2K, 4K, 8k etc. +@param aPciAddress On success, will be a PCI address by which the chunk may be accessed +@return + - KErrNone - On Success + - KErrInUse - aChunk was not NULL + - KErrNotFound - All of Bridge's BARS have been used up. Free one with RemoveChunk + - KErrArgument - aSize was less than 1. +*/ +TInt DNaviEnginePciBridge::CreateChunk(DChunk*& aChunk, TChunkCreateInfo &aAttributes, TUint aOffset, TUint aSize, TUint32& aPciAddress) + { + if(aChunk!=NULL) + return KErrInUse; + if(aSize<1) + return KErrArgument; + + return iChunkMan.AddChunk(aChunk, aAttributes, aOffset, aSize, aPciAddress); + } + + +TInt DNaviEnginePciBridge::RemoveChunk(DPlatChunkHw* aChunk) + { + return iChunkMan.RemoveChunk(aChunk); + } + +TInt DNaviEnginePciBridge::CreateMapping(TUint32 aPhysicalAddress, TInt aSize, TUint32& aPciAddress) + { + if(aSize<1) + return KErrArgument; + + return iMapMan.CreateMapping(aPhysicalAddress, aSize, aPciAddress); + } + +TInt DNaviEnginePciBridge::RemoveMapping(TUint32 aPhysicalAddress) + { + return iMapMan.RemoveMapping(aPhysicalAddress); + } + +TInt DNaviEnginePciBridge::GetPciAddress(TUint32 aPhysicalAddress, TUint32& aPciAddress) + { + return iMapMan.GetPciAddress(aPhysicalAddress, aPciAddress); + } + +TInt DNaviEnginePciBridge::GetPhysicalAddress(TUint32 aPciAddress, TUint32& aPhysicalAddress) + { + return iMapMan.GetPhysicalAddress(aPciAddress, aPhysicalAddress); + } + +/** +Attempt to access function at this location. If it exists then scan its +bars to create required PCI memory space. +Create and return a complete TPciFunction +*/ +TPciFunction* DNaviEnginePciBridge::Function(TInt aBus, TInt aDevice, TInt aFunction) + { + const TUint32 val = ReadConfig32(aBus, aDevice, aFunction, 0x0); + + //the function does not exist. + if(val == 0xFFFFFFFF) + return NULL; + + const TInt16 vid=val&0xFFFF; + TInt16 did=(val>>16)&0xFFFF; + + //don't give access to the bridge its self + if(vid==iVid && did==iDid) + return NULL; + + TPciFunction* func= new TPciFunction(aBus, aDevice, aFunction, vid, did, *this); + if(NULL==func) + return func; + + TAddrSpace& configSpace=*func->GetConfigSpace(); + + TInt r=KErrNone; + //scan each of the bars + for(TInt i=0; iAddMemorySpace(size, pciAddress+iVirtualWindow, i); + if(r!=KErrNone) + break; + + //modify bar. + configSpace.Write32(barOffset, pciAddress); + } + + if(r==KErrNone) + { + configSpace.Modify16(KHoPciCmd, NULL, KHtPcicmd_Memen); + return func; + } + else + { + delete func; + return NULL; + } + + } + +void DNaviEnginePciBridge::ConfigurationComplete() + { + //state that config is complete and allow subsequent master aborts + //to trigger the error interrupt + AsspRegister::Modify32(iBaseAddr+KHoPciCtrlH, NULL, KHtPciCtrlH_CnfigDone| KHtPciCtrlH_Mase); + Interrupt::Enable(EIntPciInt); + } + + +void DNaviEnginePciBridge::ErrorPrint() + { + Kern::Printf("Pci Errors:"); + + Kern::Printf(" Status Register"); + volatile TUint16 status=AsspRegister::Read16(iBaseAddr+KHoPciStatus); + if(status & KHtPciStatus_ParityError) + Kern::Printf(" Parity Error"); + if(status & KHtPciStatus_SystemError) + Kern::Printf(" System Error"); + if(status & KHtPciStatus_MasterAbrtRcvd) + Kern::Printf(" MasterAbrtRcvd"); + if(status & KHtPciStatus_TargetAbrtRcvd) + Kern::Printf(" TargetAbrtRcvd"); + if(status & KHtPciStatus_DPErrorAsserted) + Kern::Printf(" PERR# asserted"); + + Kern::Printf(" Err1 Register:"); + volatile TUint32 error=AsspRegister::Read32(iBaseAddr+KHoError1); + if(error & KHtError1_SystemError) + Kern::Printf(" System Error"); + if(error & KHtError1_AMEr) + Kern::Printf(" AHB master error"); + + Kern::Printf(" PciCtrlHi Register"); + + volatile TUint32 pciCtrlH=AsspRegister::Read32(iBaseAddr+KHoPciCtrlH); + if(pciCtrlH & KHtPciCtrlH_Aper) + Kern::Printf(" Address Parity error"); + if(pciCtrlH & KHtPciCtrlH_Dtep) + Kern::Printf(" Discard time out"); + if(pciCtrlH & KHtPciCtrlH_Dper) + Kern::Printf(" Data parity error"); + if(pciCtrlH & KHtPciCtrlH_Rlex) + Kern::Printf(" Retry limit exceeded"); + if(pciCtrlH & KHtPciCtrlH_Mabo) + Kern::Printf(" Master abort"); + if(pciCtrlH & KHtPciCtrlH_Tabo) + Kern::Printf(" Target abort"); + + } +/** +@param aOffset A DWord index (32 bit) +@return A value sutiable for writing to the bridge's CNFIG_ADDR register +*/ +TCnfgAddr DNaviEnginePciBridge::MakeConfigAddress(TInt aBus, TInt aDevice, TInt aFunction, TUint aDwordOffset) + { + using namespace ConfigAddress; + const TUint32 bus=(aBus<>2; //divide by 4 + const TUint byteOffset = aOffset%4; + + const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); + + Wait(); + AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); + volatile TUint8 value = AsspRegister::Read8(iBaseAddr+KHoCnfig_data+byteOffset); + Signal(); + return value; + } + +TUint16 DNaviEnginePciBridge::ReadConfig16(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset) const + { + const TUint dwordOffset = aOffset>>2; //divide by 4 + const TUint byteOffset = aOffset%4; + + const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); + + Wait(); + AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); + volatile TUint16 value = AsspRegister::Read16(iBaseAddr+KHoCnfig_data+byteOffset); + Signal(); + return value; + } + +/** +@param aOffset A byte index +*/ +TUint32 DNaviEnginePciBridge::ReadConfig32(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset) const + { + TUint dwordOffset = aOffset>>2; //divide by 4 + + const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); + + Wait(); + AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); + volatile TInt32 value = AsspRegister::Read32(KHoCnfig_data+iBaseAddr); + Signal(); + return value; + } + +void DNaviEnginePciBridge::WriteConfig8(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint8 aValue) + { + TUint dwordOffset = aOffset>>2; //divide by 4 + const TUint byteOffset = aOffset%4; + + const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); + + Wait(); + AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); + AsspRegister::Write8(KHoCnfig_data+iBaseAddr+byteOffset, aValue); + Signal(); + } + +void DNaviEnginePciBridge::WriteConfig16(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint16 aValue) + { + TUint dwordOffset = aOffset>>2; //divide by 4 + const TUint byteOffset = aOffset%4; + + const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); + + Wait(); + AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); + AsspRegister::Write16(KHoCnfig_data+iBaseAddr+byteOffset, aValue); + Signal(); + } + +/** +@param aOffset A byte index +*/ +void DNaviEnginePciBridge::WriteConfig32(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint32 aValue) + { + //__KTRACE_OPT(KPCI, Kern::Printf("PCI: WriteConfig32: %x:%x:%x os=%x, val=%x ", aBus,aDevice, aFunction, aOffset, aValue)); + TUint dwordOffset = aOffset>>2; //divide by 4 + const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); + + Wait(); + AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); + AsspRegister::Write32(KHoCnfig_data+iBaseAddr, aValue); + Signal(); + } + +void DNaviEnginePciBridge::ModifyConfig8(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint8 aClearMask, TUint8 aSetMask) + { + //__KTRACE_OPT(KPCI, Kern::Printf("PCI: ModifyConfig32: %x:%x:%x os=%x, clear=%x, set=%x ",aBus,aDevice, aFunction, aOffset, aClearMask, aSetMask)); + TUint dwordOffset = aOffset>>2; //divide by 4 (and trunctate) + const TUint byteOffset = aOffset%4; + + const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); + + Wait(); + AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); + AsspRegister::Modify8(KHoCnfig_data+iBaseAddr+byteOffset, aClearMask, aSetMask); + Signal(); + } + +void DNaviEnginePciBridge::ModifyConfig16(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint16 aClearMask, TUint16 aSetMask) + { + //__KTRACE_OPT(KPCI, Kern::Printf("PCI: ModifyConfig32: %x:%x:%x os=%x, clear=%x, set=%x ",aBus,aDevice, aFunction, aOffset, aClearMask, aSetMask)); + TUint dwordOffset = aOffset>>2; //divide by 4 (and trunctate) + const TUint byteOffset = aOffset%4; + + const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); + + Wait(); + AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); + AsspRegister::Modify16(KHoCnfig_data+iBaseAddr+byteOffset, aClearMask, aSetMask); + Signal(); + } + +void DNaviEnginePciBridge::ModifyConfig32(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint32 aClearMask, TUint32 aSetMask) + { + //__KTRACE_OPT(KPCI, Kern::Printf("PCI: ModifyConfig32: %x:%x:%x os=%x, clear=%x, set=%x ",aBus,aDevice, aFunction, aOffset, aClearMask, aSetMask)); + TUint dwordOffset = aOffset>>2; //divide by 4 (and trunctate) + + const TCnfgAddr location = MakeConfigAddress(aBus, aDevice, aFunction, dwordOffset); + + Wait(); + AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, location); + AsspRegister::Modify32(KHoCnfig_data+iBaseAddr, aClearMask, aSetMask); + Signal(); + } + +void DNaviEnginePciBridge::InitialiseRegisters() + { + ClearRegisters(); + + //make the bridge a PCI master and respond as a target + AsspRegister::Modify16(iBaseAddr+KHoPciCmd, 0x0, KHtPcicmd_Bmasen|KHtPcicmd_Memen|KHtPcicmd_Peren|KHtPcicmd_Seren); + + //set up inbound access to PCI through window 1. + const TUint32 window1Register = + 0| //window points to address 0 of PCI + (0x13<(aP); + __KTRACE_OPT(KPCI, + Kern::Printf("Pci interrupt line: Bridge Base address 0x%08x",bridge->iBaseAddr); + bridge->ErrorPrint(); + ); + + volatile TUint16 status=AsspRegister::Read16((bridge->iBaseAddr)+KHoPciStatus); + if(status & KHtPciStatus_SystemError) + { + Kern::Fault("PCI System Error: Fatal",0); + } + bridge->ClearErrors(); + } + +// +// TNaviEngineChunkCleanup // +// + +TNaviEngineChunkCleanup::TNaviEngineChunkCleanup(TChunkManager& aChunkMan, TUint32 aPhysicalAddress) + :TChunkCleanup(), iChunkMan(aChunkMan), iPhysicalAddress(aPhysicalAddress) + { + } + +TNaviEngineChunkCleanup::~TNaviEngineChunkCleanup() + { + } + +void TNaviEngineChunkCleanup::Destroy() + { + iChunkMan.RemoveChunk(iPhysicalAddress); + } + + +DECLARE_STANDARD_EXTENSION() + { + __KTRACE_OPT(KEXTENSION, Kern::Printf("Pci Extension starting...")); + + DPciBridge* internBridge = new DNaviEnginePciBridge(KHwPciBridgeUsb, KHwUsbHWindow); + + if(internBridge == NULL) + return KErrNoMemory; + + TInt r = internBridge->Initialise(); + if(r !=KErrNone) + return r; + + r = internBridge->Register(); + if(r !=KErrNone) + { + delete internBridge; + return r; + } + + r = Pci::Enumerate(); + return r; + } + + + + + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/pci/pci-ne.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/pci/pci-ne.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,131 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#ifndef _PCI_NE_H +#define _PCI_NE_H + +#include "allocator.h" +#include "mapman.h" +#include "chunkman.h" +#include +#include "pci_priv.h" + +typedef TUint32 TCnfgAddr; + +const TUint32 KPciAddressSpaceSize = 0x80000000; //2GB + +const TInt32 KMinOutboundWindow = 0x400; + +const TUint16 KNecVendorId=0x1033; +const TUint16 KInternalPciBridgeId=0x0175; +const TUint16 KExternalPciBridgeId=0x0174; + +class TNaviEngineChunkCleanup : public TChunkCleanup + { +public: + TNaviEngineChunkCleanup(TChunkManager& aChunkMan, TUint32 aPhysicalAddress); + ~TNaviEngineChunkCleanup(); + void Destroy(); + +private: + TChunkManager& iChunkMan; //< The chunk manager used by the NaviEngine host bridge + TUint32 iPhysicalAddress; //< Required to free physical memory and unmap memory from Pci + }; + + + +/** +This represents a PCI host bridge controller on the NaviEngine, there are +two identical ones, one for external peripherals and one dedicated +to the OHCI and EHCI usb host controllers. + +The main job of the class is to manage the address mappings which control +access across the bridge. For access to a PCI address from the AHB bus, there +is a window region in AHB space for which accesses will be forwarded to the bridge. +The bridge can then convert that AHB address before accessing the PCI bus. + +It is also possible for devices on the PCI side to access addresses on the AHB side (DMA). +This is done by configuring the BARs on the bridge device to respond to selected PCI +addresses and forward these accesses on to the AHB bus. This is functionallity +is accessed with the CreateChunk method. +*/ +class DNaviEnginePciBridge : public DPciBridge + { +public: + DNaviEnginePciBridge(TUint aBaseAddress, TUint32 aVirtualWindow); + TInt Initialise(); + ~DNaviEnginePciBridge(); + + TPciFunction* Function(TInt aBus, TInt aDevice, TInt aFunction); + void ConfigurationComplete(); + TInt CreateChunk(DPlatChunkHw*& aChunk, TInt aSize, TUint aAttributes, TUint32& aPciAddress); + TInt CreateChunk(DChunk*& aChunk, TChunkCreateInfo &aAttributes, TUint aOffset, TUint aSize, TUint32& aPciAddress); + TInt RemoveChunk(DPlatChunkHw* aChunk); + + TInt CreateMapping(TUint32 aPhysicalAddress, TInt aSize, TUint32& aPciAddress); + TInt RemoveMapping(TUint32 aPhysicalAddress); + TInt GetPciAddress(TUint32 aPhysicalAddress, TUint32& aPciAddress); + TInt GetPhysicalAddress(TUint32 aPciAddress, TUint32& aPhysicalAddress); + + void ErrorPrint(); + + TUint8 ReadConfig8(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset) const; + TUint16 ReadConfig16(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset) const; + TUint32 ReadConfig32(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset) const; + + void WriteConfig8(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint8 aValue); + void WriteConfig16(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint16 aValue); + void WriteConfig32(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint32 aValue); + + void ModifyConfig8(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint8 aClearMask, TUint8 aSetMask); + void ModifyConfig16(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint16 aClearMask, TUint16 aSetMask); + void ModifyConfig32(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint32 aClearMask, TUint32 aSetMask); + +private: + void InitialiseRegisters(); + void ClearRegisters(); + void ClearErrors(); + + TInt SetupInterrupts(); + static TCnfgAddr MakeConfigAddress(TInt aBus, TInt aDevice, TInt aFunction, TUint aDwordOffset); + inline void Wait() const + {NKern::FMWait(&iConfigLock);} + inline void Signal() const + {NKern::FMSignal(&iConfigLock);} + + TUint ProbeBar(TAddrSpace& aCs, TUint32 aBarOffset); + + + // ISRs // + static void PciISR(void* aP); + static void ParityErrorISR(void* aP); + static void SystemErrorISR(void* aP); + + const TUint32 iBaseAddr; + const TUint32 iVirtualWindow; //The kernel-side virtual address which is used to access PCI bus + + mutable NFastMutex iConfigLock; //make access to config addrss and data ports atomic + + TAddressAllocator iAllocator; + TMappingManager iMapMan; + TChunkManager iChunkMan; + const TUint16 iVid; + const TUint16 iDid; + }; +#endif //_PCI_NE_H diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/pci/pci-test.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/pci/pci-test.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(pci-test,dll) +targettype kext +linkas pci-test.dll + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +sourcepath ./ +source test.cpp +source allocator.cpp +source mapman.cpp + +library VariantTarget(kanaviengine,lib) +library VariantTarget(pci,lib) + +capability all + +vendorid 0x70000001 +epocallowdlldata diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/pci/pci.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/pci/pci.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,519 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include +#include +#include + +#include "pci_priv.h" + +// +// TAddrSpace class +// + +TAddrSpace::TAddrSpace(TUint aSize, const TDesC& aName) + :iSize(aSize), iName(aName) + { + } + +EXPORT_C TUint TAddrSpace::Size() + { + return iSize; + } + +/** +Check access is aligned and in range +*/ +void TAddrSpace::CheckAccess(TNumberOfBytes aNumberOfBytes, TUint aByteOffset) + { + if(aByteOffset > iSize-aNumberOfBytes) + { + Kern::Printf("PCI %S: Access out of range", &iName); + FAULT(); + } + if(aByteOffset%aNumberOfBytes) + { + Kern::Printf("PCI %S: Access missaligned", &iName); + FAULT(); + } + } + +// +// DPciBridge class +// +DPciBridge::DPciBridge() + { + } + +DPciBridge::~DPciBridge() + { + } + + +/** +Register this bridge with the system wide Pci manager. +*/ +TInt DPciBridge::Register() + { + return Pci::AddBridge(this); + } + + +// +// Pci class +// + +TBool Pci::iEnumerated = EFalse; + +RPointerArray Pci::iPciBridges(2); + +/** +Search all PCI busses for PCI functions matching the specified vendor and +device ids. + +@param aVid Vendor Id +@param aDid Device Id +@param aListOfFunctions On KErrNone will be filled with indices of matching PCI functions +@return + - KErrNone - Matching functions were found + - KErrNotFound - No matches were found. + - KErrArgument - aListOfFunctions was not empty at start. +*/ +EXPORT_C TInt Pci::Probe(RArray& aListOfFunctions, TPciVendorId aVid, TDeviceId aDid) + { + if(aListOfFunctions.Count()>0) + return KErrArgument; + + const TInt functionCount=iFunctions.Count(); + TInt r=KErrNotFound; + for(TInt i=0; iVendorId()==aVid && func->DeviceId()==aDid) + { + r = aListOfFunctions.Append(i); + if(r!=KErrNone) + return r; //some error when appending + } + } + + if(aListOfFunctions.Count()>0) + r=KErrNone; + + return r; + } + +/** +Gets a pointer to one of the specified function's memory +spaces. A function may have a memory space for each of its +6 BARS. If either of the supplied indices are invalid NULL +will be returned. + +@return NULL if error, otherwise a pointer the requested memory space. +@param aFunction Index of the PCI function. +@param aBarIndex Index from 0 to 5 +*/ +EXPORT_C TAddrSpace* Pci::GetMemorySpace(TInt aFunction, TInt aBarIndex) + { + if(!Rng(0, aFunction, iFunctions.Count()-1 )) + return NULL; + return iFunctions[aFunction]->GetMemorySpace(aBarIndex); + } + +/** +Get a pointer to the specified function's configuration space. + +@return NULL if aFunction is invalid or some other error +@param aFunction Index of the PCI function. +*/ +EXPORT_C TAddrSpace* Pci::GetConfigSpace(TInt aFunction) + { + if(!Rng(0, aFunction, iFunctions.Count()-1 )) + return NULL; + + return iFunctions[aFunction]->GetConfigSpace(); + } + +/** +Create a DMA'able DPlatChunkHw chunk with memory allocated which will be accessable by the PCI function aFunction (and other PCI devices +on the same bridge). The allocated chunk must only be destroyed with Pci::RemoveChunk. For simplicity +it is recommended to use the alternate CreateChunk to create a DChunk, since this will be a able to clean itself up automatically on +closure. +@return + - KErrNone on success + - KErrInUse - aChunk was not NULL + - KErrNotFound - All of Bridge's BARS have been used up. Free one with RemoveChunk + - KErrArgument - aSize was less than 1. +@param aFunction Index of the PCI function. +@param aChunk Must be NULL, on success will point to the created chunk. +@param aSize of chunk required. +This will be rounded up to the next power of 2 in kilobytes +.eg 1K, 2K, 4K etc. So requesting a 600Kb buffer will result in 1Mb being allocated. +@param aAttributes Attribute mask made up of OR'd values in TMappingAttributes +@param aPciAddress On success will be set to the PCI address with which devices may access the allocated memory. +*/ +EXPORT_C TInt Pci::CreateChunk(TInt aFunction, DPlatChunkHw*& aChunk, TInt aSize, TUint aAttributes, TUint32& aPciAddress) + { + if(!Rng(0, aFunction, iFunctions.Count()-1 )) + return KErrArgument; + + return iFunctions[aFunction]->GetBridge().CreateChunk(aChunk, aSize, aAttributes, aPciAddress); + } + +/** +Create a DMA'able chunk with memory allocated which will be accessable by the PCI function aFunction (and other PCI devices +on the same bridge). When the final reference to the chunk is closed it will be unmapped from PCI memory and free its physical ram. +@return + - KErrNone on success + - KErrInUse - aChunk was not NULL + - KErrNotFound - All of Bridge's BARS have been used up. Free one by calling RemoveMapping, RemoveChunk or closing all + references to a DChunk previously allocated with this function. + - KErrArgument - aSize was less than 1. +@param aFunction Index of the PCI function. +@param aChunk Must be NULL, on success will point to the created chunk. +@param aAttributes Contains creation parameters for DChunk. These may be adjusted by the driver and can be viewed on return +@param aOffset The number of bytes into the chunk's virtual address range at which memory should be commited. +@param aSize of chunk required. +This will be rounded up to the next power of 2 in kilobytes +.eg 1K, 2K, 4K etc. So requesting a 600Kb buffer will result in 1Mb being allocated. +@param aPciAddress On success will be set to the PCI address with which devices may access the allocated memory. +*/ +EXPORT_C TInt Pci::CreateChunk(TInt aFunction, DChunk*& aChunk, TChunkCreateInfo &aAttributes, TUint aOffset, TUint aSize, TUint32& aPciAddress) + { + if(!Rng(0, aFunction, iFunctions.Count()-1 )) + return KErrArgument; + + return iFunctions[aFunction]->GetBridge().CreateChunk(aChunk, aAttributes, aOffset, aSize, aPciAddress); + } + +RPointerArray Pci::iFunctions; + + +/** +Remove mapping from PCI memory space to chunk. +Free the memory chunk's memory and chunk object itself. + +@param aFunction The PCI function wth which the chunk was associated. +@param aChunk Pointer to the chunk to be deleted +@return + - KErrNone on success + - KErrArgument aFunction was invalid + - KErrNotFound aChunk was not found +*/ +EXPORT_C TInt Pci::RemoveChunk(TInt aFunction, DPlatChunkHw* aChunk) + { + if(!Rng(0, aFunction, iFunctions.Count()-1 )) + return KErrArgument; + + return iFunctions[aFunction]->GetBridge().RemoveChunk(aChunk); + } + +EXPORT_C void Pci::ChunkCleanupCallback(TChunkCleanup* aCleanup) + { + __KTRACE_OPT(KPCI, Kern::Printf("Pci::ChunkCleanupCallback aCleanup = 0x%08x", aCleanup)); + aCleanup->Destroy(); + delete aCleanup; + } + +EXPORT_C TInt Pci::CreateMapping(TInt aFunction, TUint32 aPhysicalAddress, TInt aSize, TUint32& aPciAddress) + { + if(!Rng(0, aFunction, iFunctions.Count()-1 )) + return KErrArgument; + __KTRACE_OPT(KPCI, Kern::Printf("Pci::CreateMapping() requested 0x%X bytes", aSize)); + return iFunctions[aFunction]->GetBridge().CreateMapping(aPhysicalAddress, aSize, aPciAddress); + } + +EXPORT_C TInt Pci::RemoveMapping(TInt aFunction, TUint32 aPhysicalAddress) + { + if(!Rng(0, aFunction, iFunctions.Count()-1 )) + return KErrArgument; + + return iFunctions[aFunction]->GetBridge().RemoveMapping(aPhysicalAddress); + } + +/** +Returns the PCI address corresponding to a given physical address. +@param aFunction +@param aAddress The physical address, on success, will have been converted to the +equivilant PCI address. +@return + - KErrNone + - KErrNotFound The physical address has no corresponding PCI address +*/ +EXPORT_C TInt Pci::GetPciAddress(TInt aFunction, TUint32& aAddress) + { + if(!Rng(0, aFunction, iFunctions.Count()-1 )) + return KErrArgument; + + return iFunctions[aFunction]->GetBridge().GetPciAddress(aAddress, aAddress); + } + +/** +Returns the physical address corresponding to a given PCI address. +@param aFunction +@param aAddress The PCI address, on success, will have been converted to the +equivilant physical address. +@return + - KErrNone + - KErrNotFound The PCI address has no corresponding physical address +*/ +EXPORT_C TInt Pci::GetPhysicalAddress(TInt aFunction, TUint32& aAddress) + { + if(!Rng(0, aFunction, iFunctions.Count()-1 )) + return KErrArgument; + + return iFunctions[aFunction]->GetBridge().GetPhysicalAddress(aAddress,aAddress); + } + + +/** +Add bridges before calling Enumerate. + +@param aBridge A constructed bridge object. +@return An error value +*/ +TInt Pci::AddBridge(DPciBridge* aBridge) + { + return iPciBridges.Append(aBridge); + } + +/** +Query all host bridges on the system for their PCI functions and +populate global function list. + +@return + - KErrNone - Success + - KErrNotSupported - No bridges have been registered + - KErrAccessDenied - Enumerate has already been called +*/ +TInt Pci::Enumerate() + { + __KTRACE_OPT(KPCI, Kern::Printf("Pci::Enumerate")); + + //only call once, from the extension + if(iEnumerated) + return KErrAccessDenied; + iEnumerated = ETrue; + + const TInt numberOfPciBridges= iPciBridges.Count(); + if(0 == numberOfPciBridges) + return KErrNotSupported; + + TInt r=KErrNone; + for(TInt bridge=0; bridgeFunction(bus, device, function); + if(func==NULL) + continue; + if(func->IsBridge()) + { + //will call bridge fix up code here when supported. + //don't add a bridge into global list as we do not want to + //grant access to it to the client programmer. + __KTRACE_OPT(KPCI, Kern::Printf( "PCI-PCI bridge unsupported")); + delete func; + func = NULL; + continue; + } + else + { + r=iFunctions.Append(func); + __KTRACE_OPT(KPCI, Kern::Printf(" Adding function %d:%d:%d:%d, vid=0x%04x, did=0x%04x" + , bridge, bus, device, function, func->VendorId(), func->DeviceId())); + } + if(r!=KErrNone) + return r; + + //a multifunction device can indicate the last function + //implemented by setting its multi function bit to 0 + //so this is checked for all function numbers + if(!func->IsMultiFunc()) + { + break; + } + } + } + } + iPciBridges[bridge]->ConfigurationComplete(); + } + return r; + } + +TPciFunction::TPciFunction(TInt aBus, TInt aDevice, TInt aFunction, + TPciVendorId aVid, TDeviceId aDid, DPciBridge& aBridge) + :iBus(aBus), iDevice(aDevice), iFunction(aFunction), iVid(aVid), iDid(aDid), + iBridge(aBridge), iConfigSpace(NULL), iMemorySpaces(KPciNumberOfBars), + iIsBridge(EFalse), iIsMultiFunc(EFalse) + { + __ASSERT_DEBUG(iBus<256, Kern::Printf("TConfigSpace: Bus id too big")); + __ASSERT_DEBUG(iDevice<32, Kern::Printf("TConfigSpace: Device id too big")); + __ASSERT_DEBUG(iFunction<8, Kern::Printf("TConfigSpace: Function id too big")); + + //Array has an element for each of this PCI function's BARs + //but an unused one will be NULL + for(TInt i=0; iRead8(KPciHeaderType); + iIsMultiFunc = (headerTypeByte & HeaderType::KHtMultiFunction); + + const TInt headerType = headerTypeByte & (~HeaderType::KHtMultiFunction); + _LIT(KHeaderError, "Unknown PCI header type"); + switch(headerType) + { + case 0: + iIsBridge=EFalse; break; + case 1: + iIsBridge=ETrue; break; + default: + Kern::PanicCurrentThread(KHeaderError, 0); + } + } + +TPciFunction::~TPciFunction() + { + iMemorySpaces.ResetAndDestroy(); + + delete iConfigSpace; + } + +/** +@param aBarIndex The Bar which this memory space is asssociated with +*/ +TInt TPciFunction::AddMemorySpace(TUint32 aSize, TUint32 aAddress, TInt aBarIndex) + { + TMemorySpace* space=new TMemorySpace(aAddress, aSize); + if(NULL==space) + { + return KErrNoMemory; + } + else + { + iMemorySpaces[aBarIndex]=space; + return KErrNone; + } + } + +EXPORT_C TAddrSpace* TPciFunction::GetConfigSpace() + { + return iConfigSpace; + } + +EXPORT_C TAddrSpace* TPciFunction::GetMemorySpace(TInt aBar) + { + if(!Rng(0,aBar, iMemorySpaces.Count()-1)) + return NULL; + + return iMemorySpaces[aBar]; + } +// +// TMemory Space +// + +#define READ_TRACE(N) __KTRACE_OPT(KPCI, Kern::Printf( "TMemorySpace::READ" #N " Offset=0x%x, Absolute=0x%x (Base=0x%x), Value=0x%x",\ + aOffset, iBaseAddress+aOffset, iBaseAddress, value )) + +#define WRITE_TRACE(N) __KTRACE_OPT(KPCI, Kern::Printf( "TMemorySpace::Write" #N " Offset=0x%x, Absolute=0x%x (Base=0x%x), Value=0x%x",\ + aOffset, iBaseAddress+aOffset, iBaseAddress, aValue )) + +#define MOD_TRACE(N) __KTRACE_OPT(KPCI, Kern::Printf( "TMemorySpace::Modify" #N " Offset=0x%x, Absolute=0x%x (Base=0x%x), ClearMask=0x%x, SetMask=0x%x",\ + aOffset, iBaseAddress+aOffset, iBaseAddress, aClearMask, aSetMask )) + +_LIT(KTMemorySpace, "TMemorySpace"); +TMemorySpace::TMemorySpace(TUint32 aBaseAddress, TUint aSize) + :TAddrSpace(aSize, KTMemorySpace), iBaseAddress(aBaseAddress) + { + } + +TUint32 TMemorySpace::Read32(TUint32 aOffset) + { + CheckAccess(E4Byte, aOffset); + return AsspRegister::Read32(iBaseAddress+aOffset); + } + +void TMemorySpace::Write32(TUint32 aOffset, TUint32 aValue) + { + WRITE_TRACE(32); + CheckAccess(E4Byte, aOffset); + AsspRegister::Write32(iBaseAddress+aOffset, aValue); + } + +void TMemorySpace::Modify32(TUint32 aOffset, TUint32 aClearMask, TUint32 aSetMask) + { + MOD_TRACE(32); + CheckAccess(E4Byte, aOffset); + AsspRegister::Modify32(iBaseAddress+aOffset, aClearMask, aSetMask); + } + +TUint16 TMemorySpace::Read16(TUint32 aOffset) + { + CheckAccess(E2Byte, aOffset); + return AsspRegister::Read16(iBaseAddress+aOffset); + } + +void TMemorySpace::Write16(TUint32 aOffset, TUint16 aValue) + { + WRITE_TRACE(16); + CheckAccess(E2Byte, aOffset); + AsspRegister::Write16(iBaseAddress+aOffset, aValue); + } + +void TMemorySpace::Modify16(TUint32 aOffset, TUint16 aClearMask, TUint16 aSetMask) + { + MOD_TRACE(16); + CheckAccess(E2Byte, aOffset); + AsspRegister::Modify16(iBaseAddress+aOffset, aClearMask, aSetMask); + } + +TUint8 TMemorySpace::Read8(TUint32 aOffset) + { + CheckAccess(E1Byte, aOffset); + return AsspRegister::Read8(iBaseAddress+aOffset); + } + +void TMemorySpace::Write8(TUint32 aOffset, TUint8 aValue) + { + WRITE_TRACE(8); + CheckAccess(E1Byte, aOffset); + AsspRegister::Write8(iBaseAddress+aOffset, aValue); + } + +void TMemorySpace::Modify8(TUint32 aOffset, TUint8 aClearMask, TUint8 aSetMask) + { + MOD_TRACE(8); + CheckAccess(E1Byte, aOffset); + AsspRegister::Modify8(iBaseAddress+aOffset, aClearMask, aSetMask); + } + +// +// TChunkCleanup +// + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/pci/pci.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/pci/pci.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,139 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +/** + @file + @publishedPartner + @test +*/ + +#ifndef _PCI_H +#define _PCI_H + +#include + +typedef TUint16 TPciVendorId; +typedef TUint16 TDeviceId; +typedef TUint16 TSubSysId; +typedef TUint16 TSubSysVendorId; + +const TUint KCfgSpaceSize = 256; // bytes + +const TInt KPciMaxBusses = 1; //This can be 256, but this driver doesn't need to support subordinate busses yet +const TInt KPciMaxDevices = 32; +const TInt KPciMaxFunctions = 8; + +const TInt KPciNumberOfBars=6; +const TUint KPciBar0 = 0x10; +const TUint KPciHeaderType = 0xE; + +/** +Bitmasks for standard PCI Base address register. +*/ +namespace Bar + { + const TUint32 KHtMemSpaceType = KBit0; // Mem or Io address space + const TUint32 KHmType = KBit1|KBit2; //32 bit or 64 bit bar + const TUint32 KHtPreFetchable = KBit3; // Set if memspace is prefetchable + } + +/** +Bitmask for standard PCI header register +*/ +namespace HeaderType + { + const TUint32 KHtMultiFunction = KBit7; //True if the device is multifunction + } + +class TAddrSpace; +class TPciFunction; +class TChunkCleanup; +class DPciBridge; +class DChunk; +class DPlatChunkHw; +struct TChunkCreateInfo; + +/** +A static class initialised in the kernel extension +to enumerate the system's PCI buses and grant access to +PCI functions. +*/ +class Pci + { +public: + IMPORT_C static TInt Probe(RArray& aListOfFunctions, TPciVendorId aVid, TDeviceId aDid); + IMPORT_C static TAddrSpace* GetMemorySpace(TInt aFunction, TInt aBarIndex=0); + IMPORT_C static TAddrSpace* GetConfigSpace(TInt aFunction); + IMPORT_C static TInt CreateChunk(TInt aFunction, DPlatChunkHw*& aChunk, TInt aSize, + TUint aAttributes, TUint32& aPciAddress); + IMPORT_C static TInt CreateChunk(TInt aFunction, DChunk*& aChunk, TChunkCreateInfo &aAttributes, + TUint aOffset, TUint aSize, TUint32& aPciAddress); + IMPORT_C static TInt RemoveChunk(TInt aFunction, DPlatChunkHw* aChunk); + IMPORT_C static TInt CreateMapping(TInt aFunction, TUint32 aPhysicalAddress, TInt aSize, + TUint32& aPciAddress); + IMPORT_C static TInt RemoveMapping(TInt aFunction, TUint32 aPhysicalAddress); + IMPORT_C static TInt GetPciAddress(TInt aFunction, TUint32& aAddress); + IMPORT_C static TInt GetPhysicalAddress(TInt aFunction, TUint32& aAddress); + + + static TInt Enumerate(); +protected: + friend class DPciBridge; + static TInt AddBridge(DPciBridge* aBridge); + + friend class TChunkCleanup; //!< Allow Cleanup object to use callback + IMPORT_C static void ChunkCleanupCallback(TChunkCleanup* aCleanup); + + static TBool iEnumerated; //!< Is toggled after enummeration + static RPointerArray iPciBridges; //!< All the bridges on the system + static RPointerArray iFunctions; //!< A system wide list of available PCI functions + }; + + +#define READ(n) virtual TUint##n Read##n(TUint32 aOffset) +#define WRITE(n) virtual void Write##n(TUint32 aOffset, TUint##n aValue) +#define MODIFY(n) virtual void Modify##n(TUint32 aOffset, TUint##n aClearMask, TUint##n aSetMask) +/** +Allows reads and writes to a section of address space. +*/ +class TAddrSpace + { +public: + IMPORT_C TUint Size(); + + IMPORT_C READ(8) =0; + IMPORT_C READ(16) =0; + IMPORT_C READ(32) =0; + + IMPORT_C WRITE(8) =0; + IMPORT_C WRITE(16) =0; + IMPORT_C WRITE(32) =0; + + IMPORT_C MODIFY(8) =0; + IMPORT_C MODIFY(16) =0; + IMPORT_C MODIFY(32) =0; +protected: + enum TNumberOfBytes {E1Byte=1, E2Byte=2, E4Byte=4}; + void CheckAccess(TNumberOfBytes aNumberOfBytes, TUint aByteOffset); + + TAddrSpace(TUint aSize, const TDesC& aName); + const TUint iSize; //!< Size of address space in bytes + const TDesC& iName; //!< Used in trace messages + }; +#endif //_PCI_H diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/pci/pci.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/pci/pci.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(pci,dll) +targettype kext +linkas pci.dll + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +sourcepath ./ +source pci-ne.cpp +source pci.cpp +source allocator.cpp +source chunkman.cpp +source mapman.cpp + +library VariantTarget(kanaviengine,lib) + +capability all + +vendorid 0x70000001 +epocallowdlldata + +deffile ../~/pci.def diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/pci/pci_priv.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/pci/pci_priv.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,188 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +/** + @file + @publishedPartner + @test +*/ + +#ifndef _PCI_PRIV_H +#define _PCI_PRIV_H + +#include + +/** +An object of this type will be passed in to the chunk cleanup +callback. +A concrete class will be derived by the PSL as the exact information +needed in order to cleanup may vary. +*/ +class TChunkCleanup : public TDfc + { +public: + inline TChunkCleanup(); + inline virtual ~TChunkCleanup() + {} + inline virtual void Destroy()=0; +private: + inline static void ChunkDestroyed(TChunkCleanup* aCleanup); + }; + + +TChunkCleanup::TChunkCleanup() + :TDfc(reinterpret_cast(ChunkDestroyed), this, Kern::DfcQue0(), 0) + { + } + +/** +The static function called by the DFC +*/ +void TChunkCleanup::ChunkDestroyed(TChunkCleanup* aCleanup) + { + Pci::ChunkCleanupCallback(aCleanup); + } + +/** +Interface to PCI Host Bridge +*/ +class DPciBridge : public DBase + { +public: + ~DPciBridge(); + TInt Register(); + + virtual TInt Initialise() =0; + virtual TPciFunction* Function(TInt aBus, TInt aDevice, TInt aFunction) =0; + virtual TInt CreateChunk(DPlatChunkHw*& aChunk, TInt aSize, TUint aAttributes, TUint32& aPciAddress)=0; + virtual TInt CreateChunk(DChunk*& aChunk, TChunkCreateInfo &aAttributes, TUint aOffset, TUint aSize, TUint32& aPciAddress)=0; + virtual TInt RemoveChunk(DPlatChunkHw* aChunk)=0; + virtual TInt CreateMapping(TUint32 aPhysicalAddress, TInt aSize, TUint32& aPciAddress)=0; + virtual TInt RemoveMapping(TUint32 aPhysicalAddress)=0; + virtual TInt GetPciAddress(TUint32 aPhysicalAddress, TUint32& aPciAddress)=0; + virtual TInt GetPhysicalAddress(TUint32 aPciAddress, TUint32& aPhysicalAddress)=0; + + virtual void ConfigurationComplete()=0; + + virtual TUint8 ReadConfig8(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset) const =0; + virtual TUint16 ReadConfig16(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset) const =0; + virtual TUint32 ReadConfig32(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset) const =0; + + virtual void WriteConfig8(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint8 aValue)=0; + virtual void WriteConfig16(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint16 aValue)=0; + virtual void WriteConfig32(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint32 aValue)=0; + + virtual void ModifyConfig8(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint8 aClearMask, TUint8 aSetMask)=0; + virtual void ModifyConfig16(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint16 aClearMask, TUint16 aSetMask)=0; + virtual void ModifyConfig32(TInt aBus, TInt aDevice, TInt aFunction, TUint aOffset, TUint32 aClearMask, TUint32 aSetMask)=0; +protected: + DPciBridge(); + }; + + +/** +Gives access to one of a PCI functions's memory spaces +*/ +class TMemorySpace : public TAddrSpace + { +public: + TMemorySpace(TUint32 aBaseAddress, TUint aSize); + + READ(8); + READ(16); + READ(32); + + WRITE(8); + WRITE(16); + WRITE(32); + + MODIFY(8); + MODIFY(16); + MODIFY(32); +private: + TUint32 iBaseAddress; + }; + +class TPciFunction; +/** +Access to a PCI function's config space +*/ +class TConfigSpace : public TAddrSpace + { +public: + TConfigSpace(TPciFunction& aFunction, DPciBridge& aBridge); + + READ(8); + READ(16); + READ(32); + + WRITE(8); + WRITE(16); + WRITE(32); + + MODIFY(8); + MODIFY(16); + MODIFY(32); + +private: + TPciFunction& iFunction; //!< The function which owns this config space + DPciBridge& iBridge; //!< The Host bridge which iFunction is on + }; + +/** +Represents a single Function on a (possibly multi-function) PCI device. +*/ +class TPciFunction + { +public: + TPciFunction(TInt aBus, TInt aDevice, TInt aFunction, TPciVendorId aVid, TDeviceId aDid, DPciBridge& aBridge); + ~TPciFunction(); + + TInt AddMemorySpace(TUint32 aSize, TUint32 aAddress, TInt aBarIndex); + IMPORT_C TAddrSpace* GetMemorySpace(TInt aBar=0); + IMPORT_C TAddrSpace* GetConfigSpace(); + + inline TInt Bus() {return iBus;} + inline TInt Device() {return iDevice;} + inline TInt Function() {return iFunction;} + inline TPciVendorId VendorId() {return iVid;} + inline TDeviceId DeviceId() {return iDid;} + + inline DPciBridge& GetBridge() {return iBridge;} + + inline TBool IsBridge() {return iIsBridge;} + inline TBool IsMultiFunc() {return iIsMultiFunc;} + +protected: + const TInt iBus; + const TInt iDevice; + const TInt iFunction; + + const TPciVendorId iVid; + const TDeviceId iDid; + + DPciBridge& iBridge; //!< The Host bridge which this TPciFunction is on + TAddrSpace* iConfigSpace; + RPointerArray iMemorySpaces; + TBool iIsBridge; + TBool iIsMultiFunc; + }; + + +#endif //_PCI_PRIV_H diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/pci/test.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/pci/test.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,487 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include +#include +#include +#include +#include "allocator.h" +#include "pci-ne.h" + +#define TEST(X) __NK_ASSERT_ALWAYS(X) +#define TEST_KERRNONE(X) TEST((X)==KErrNone) + +/** +Make sure that I can read and write some values as expected +*/ +void TestConfigAccess(TAddrSpace& aCfgSpc) + { + TEST(aCfgSpc.Size()==0x100); + + TEST(aCfgSpc.Read32(0x0)==0x00351033); + + TEST(aCfgSpc.Read16(0x0)==0x1033); + + TEST(aCfgSpc.Read16(0x2)==0x0035); + + TEST(aCfgSpc.Read8(0x0)==0x33); + + TEST(aCfgSpc.Read8(0x1)==0x10); + + TEST(aCfgSpc.Read8(0x02)==0x35); + + TEST(aCfgSpc.Read8(0x3)==0x00); + + //test writes (there aren't that many contiguous blocks of writable bits in config space, but the BAR will do) + const TUint32 original= aCfgSpc.Read32(KPciBar0); + + aCfgSpc.Write32(KPciBar0,0xFFFFFFFF); + const TUint32 filled = aCfgSpc.Read32(KPciBar0); + TEST(filled==0xFFFFF000); //not all of register is writable + + aCfgSpc.Write8(KPciBar0+0x3,0xBA); + TEST(aCfgSpc.Read8(KPciBar0+0x3)== 0xBA); + TEST(aCfgSpc.Read32(KPciBar0)== 0xBAFFF000); + + aCfgSpc.Write8(KPciBar0+0x2,0x55); + TEST(aCfgSpc.Read8(KPciBar0+0x2)== 0x55); + TEST(aCfgSpc.Read32(KPciBar0)== 0xBA55F000); + + aCfgSpc.Write8(KPciBar0+0x1,0x42); + TEST(aCfgSpc.Read8(KPciBar0+0x1)== 0x40); //lower nibble unwriteable + TEST(aCfgSpc.Read32(KPciBar0)== 0xBA554000); + + aCfgSpc.Write16(KPciBar0+0x0,0x5000); + TEST(aCfgSpc.Read16(KPciBar0+0x0)== 0x5000); + TEST(aCfgSpc.Read32(KPciBar0)== 0xBA555000); + + aCfgSpc.Write16(KPciBar0+0x2,0xAAAA); + TEST(aCfgSpc.Read16(KPciBar0+0x2)== 0xAAAA); + TEST(aCfgSpc.Read32(KPciBar0)== 0xAAAA5000); + + + //test modifies + aCfgSpc.Modify8(KPciBar0+0x3, 0xFF, 0x3C); + TEST(aCfgSpc.Read8(KPciBar0+0x3) == 0x3C); + + aCfgSpc.Modify8(KPciBar0+0x2, 0xFF, 0x3C); + TEST(aCfgSpc.Read8(KPciBar0+0x2) == 0x3C); + + //restore original value. + aCfgSpc.Write32(KPciBar0, original); + TEST(aCfgSpc.Read32(KPciBar0)==original); + } + + +TBool TestMemoryAccess(TAddrSpace& memSpace) + { + TEST(memSpace.Size()==0x1000); + + //try some writes to the HcControlHeadED register - bits 31:4 are writeable + const TUint KReg=0x20; + const TUint32 initial = memSpace.Read32(KReg); + + memSpace.Write32(KReg, 0x0); + TEST(memSpace.Read32(KReg)==0x0); + + memSpace.Write32(KReg, 0xFFFFFFFF); + TEST(memSpace.Read32(KReg)==0xFFFFFFF0); //nibble0 read-only + + memSpace.Write16(KReg+2, 0xDEAD); + TEST(memSpace.Read32(KReg)==0xDEADFFF0); + + memSpace.Write16(KReg, 0xABCD); + TEST(memSpace.Read16(KReg)==0xABC0); + TEST(memSpace.Read16(KReg+2)==0xDEAD); + + memSpace.Modify32(KReg, 0x0000FFFF, 0x0F0F0000); + TEST(memSpace.Read32(KReg)==0xDFAF0000); + TEST(memSpace.Read8(KReg+3)==0xDF); + + memSpace.Write8(KReg+1,0x42); + TEST(memSpace.Read8(KReg+0)==0x00); + TEST(memSpace.Read8(KReg+1)==0x42); + TEST(memSpace.Read8(KReg+2)==0xAF); + TEST(memSpace.Read8(KReg+3)==0xDF); + TEST(memSpace.Read32(KReg)==0xDFAF4200); + + memSpace.Modify8(KReg+3,0xFF,0x10); + TEST(memSpace.Read32(KReg)==0x10AF4200); + + //reset to inital value + memSpace.Write32(KReg, initial); + TEST(memSpace.Read32(KReg)==initial); + + return ETrue; + } + +void TestAllocator() + { + __KTRACE_OPT(KPCI, Kern::Printf("Testing address allocator")); + TAddressAllocator allocator(0x80000000); //2 GB + TLinAddr rcvdAddr=NULL; + TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x10) ); + TEST(0x0 ==rcvdAddr); + TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x100) ); + TEST(0x100 ==rcvdAddr); + TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x10) ); + TEST(0x10 ==rcvdAddr); + TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x10) ); + TEST(0x20 ==rcvdAddr); + //test deallocating + TEST_KERRNONE(allocator.DeAllocate(0x0)); + TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x10) ); + TEST(0x000 ==rcvdAddr); + + TEST_KERRNONE(allocator.DeAllocate(0x100)); + TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x100) ); + TEST(0x100 ==rcvdAddr); + + TEST_KERRNONE(allocator.DeAllocate(0x10)); + TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x10) ); + TEST(0x10 ==rcvdAddr); + + TEST_KERRNONE(allocator.DeAllocate(0x20)); + TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x20) ); + TEST(0x20 ==rcvdAddr); + + TEST(allocator.DeAllocate(0x40)==KErrNotFound); + TEST_KERRNONE(allocator.DeAllocate(0x100)); + TEST_KERRNONE(allocator.DeAllocate(0x20)); + TEST_KERRNONE(allocator.DeAllocate(0x0)); + TEST_KERRNONE(allocator.DeAllocate(0x10)); + } + +/** +Wrapper to get chunk and its virtual address +*/ +TInt CreatePciChunk(TInt aFunc, TInt& aSize, TUint32 aAttributes, DPlatChunkHw*& aChunk, TUint32& aPci, TLinAddr& aVirt) + { + TInt r = Pci::CreateChunk(aFunc, aChunk, aSize, aAttributes, aPci); + if(r!=KErrNone) + return r; + + aVirt=aChunk->LinearAddress(); + + return r; + } + +/** +Wrapper to create chunk and append to array +*/ +TInt CreatePciChunkAppend(TInt aFunc, TInt aSize, TUint32 aAttributes, RPointerArray& aChunks) + { + DPlatChunkHw* chunk=NULL; + TUint32 pci=NULL; + TInt r = Pci::CreateChunk(aFunc, chunk, aSize, aAttributes, pci); + if(KErrNone==r) + { + TEST_KERRNONE(aChunks.Append(chunk)); + } + return r; + } + +TInt CreateSharedChunk(TInt aSize, TUint32& aAttributes, DChunk*& aChunk, TLinAddr& aVirt, TPhysAddr& aPhysicalAddress) + { + TEST(aChunk==NULL); + aSize = Kern::RoundToPageSize(aSize); + TChunkCreateInfo info; + info.iType=TChunkCreateInfo::ESharedKernelSingle; + info.iMaxSize=aSize; + info.iMapAttr=aAttributes; + info.iOwnsMemory=ETrue; + + DChunk* pC=NULL; + + NKern::ThreadEnterCS(); + TInt r=Kern::ChunkCreate(info, pC, aVirt, aAttributes); + if(r!=KErrNone) + { + NKern::ThreadLeaveCS(); + return r; + } + + r = Kern::ChunkCommitContiguous(pC, 0, aSize, aPhysicalAddress); + + if(r==KErrNone) + { + aChunk=pC; + } + else + { + Kern::ChunkClose(pC); + } + + NKern::ThreadLeaveCS(); + __KTRACE_OPT(KPCI, Kern::Printf("Created SC: size=0x%08x, virtual= 0x%08x, phys=0x%08x", aSize, aVirt, aPhysicalAddress)); + return r; + } + +TInt UnmapAndCloseSC(TInt aFunc, DChunk* aChunk, TPhysAddr aPhysicalAddress) + { + TInt r = Pci::RemoveMapping(aFunc, aPhysicalAddress); + TEST_KERRNONE(r); + NKern::ThreadEnterCS(); + TEST(Kern::ChunkClose(aChunk)); //test that ref count has gone to zero + NKern::ThreadLeaveCS(); + return r; + } + +TInt CreateAndMapSC(TInt aFunc, TInt aSize, TUint32 aAttributes, DChunk*& aChunk, TUint32& aPci, TLinAddr& aVirt, TPhysAddr& aPhysicalAddress) + { + TInt r = CreateSharedChunk(aSize, aAttributes, aChunk, aVirt, aPhysicalAddress); + TEST_KERRNONE(r); + TEST(aChunk); + TEST_KERRNONE(r); + r=Pci::CreateMapping(aFunc, aPhysicalAddress, aSize, aPci); + TEST_KERRNONE(r); + return r; + } + +void TestChunkAllocation(TInt func) + { + __KTRACE_OPT(KPCI, Kern::Printf("test allocating chunks")); + const TUint32 attributes= EMapAttrSupRw|EMapAttrFullyBlocking; + + //keep track of the chunks so i can delete them afterwards + RPointerArray chunkList(12); + + TEST_KERRNONE(CreatePciChunkAppend(func, 0x1000, attributes, chunkList)); + TEST_KERRNONE(CreatePciChunkAppend(func, 0x4000, attributes, chunkList)); + TEST_KERRNONE(CreatePciChunkAppend(func, 0x1000, attributes, chunkList)); + TEST_KERRNONE(CreatePciChunkAppend(func, 0x2000, attributes, chunkList)); + TEST_KERRNONE(CreatePciChunkAppend(func, 0x8000, attributes, chunkList)); + TEST_KERRNONE(CreatePciChunkAppend(func, 0x10000, attributes, chunkList)); + + TEST_KERRNONE(CreatePciChunkAppend(func, 0x8000, attributes, chunkList)); + TEST_KERRNONE(CreatePciChunkAppend(func, 0x1000, attributes, chunkList)); + TEST_KERRNONE(CreatePciChunkAppend(func, 0x4000, attributes, chunkList)); + TEST_KERRNONE(CreatePciChunkAppend(func, 0x1000, attributes, chunkList)); + TEST_KERRNONE(CreatePciChunkAppend(func, 0x2000, attributes, chunkList)); + TEST_KERRNONE(CreatePciChunkAppend(func, 0x80000, attributes, chunkList)); + + //try to allocate more chunks than there are BARS + TEST(CreatePciChunkAppend(func, 0x1000, attributes, chunkList)==KErrNotFound); + //try to allocate chunk with size less than 1 + TEST(CreatePciChunkAppend(func, 0x0, attributes, chunkList)==KErrArgument); + + __KTRACE_OPT(KPCI, Kern::Printf("Delete all chunks")); + const TInt count=chunkList.Count(); + for(TInt i=0; iPhys address conversions: func %d, pci 0x%08x, physical 0x%08x, size 0x%08x ", aFunc, aPciAddr, aPhysAddr, aSize)); + for(TInt offset=-1; offset<=aSize; ++offset) + { + const TUint32 expectedPci=aPciAddr+TInt(offset); + TUint32 address=aPhysAddr+TInt(offset); + TInt r=Pci::GetPciAddress(aFunc,address); + //__KTRACE_OPT(KPCI, Kern::Printf("GetPciAddress: offset=0x%08x, r=%d, physical=0x%08x, pci=0x%08x,expectedPci=0x%08x", + // offset, r, aPhysAddr+offset, address, expectedPci)); + if(offset==-1||offset==aSize) + { + TEST(r==KErrNotFound); //test going beyond either side of the memory region + } + else + { + TEST_KERRNONE(r); + TEST(address==expectedPci); + } + + const TUint32 expectedPhys=aPhysAddr+offset; + address=aPciAddr+offset; + r=Pci::GetPhysicalAddress(aFunc, address); + //__KTRACE_OPT(KPCI, Kern::Printf("GetPhysicalAddress: offset=0x%08x, r=%d, pci=0x%08x, physical=0x%08x, expectedPhysical=0x%08x", + // offset, r, aPciAddr+offset, address, expectedPhys)); + if(offset==-1||offset==aSize) + { + TEST(r==KErrNotFound); + } + else + { + TEST_KERRNONE(r); + TEST(address==expectedPhys); + } + } + } + +void TestPciChunkAccesses(TInt aFunc) + { + const TInt sizes[] = {0x1, 0x400, 0x800}; + const TUint32 attrs[] = {EMapAttrSupRw|EMapAttrFullyBlocking, EMapAttrSupRw|EMapAttrCachedMax}; + + __KTRACE_OPT(KPCI, Kern::Printf("Testing PCI chunk access")); + for(TInt i=0; i<3; ++i) + { + for(TInt j=0; j<2; ++j) + { + __KTRACE_OPT(KPCI, Kern::Printf("\nSize=0x%08x, attrs=0x%08x", sizes[i], attrs[j])); + TLinAddr virt=NULL; + TUint32 pci=NULL; + DPlatChunkHw* chunk=NULL; + TInt size=sizes[i];//size may be altered by CreatePciChunk if it is rounded + TInt r = CreatePciChunk(aFunc, size, attrs[j], chunk, pci, virt); + TEST_KERRNONE(r); + TestPciMemoryAccess(virt, pci, size, attrs[j]); + TestAddressConversion(aFunc, pci, chunk->PhysicalAddress(), sizes[i]); + + r = Pci::RemoveChunk(aFunc, chunk); + TEST_KERRNONE(r); + + } + } + } + +void TestWindowAccesses(TInt aFunc) + { + const TInt sizes[] = {0x1, 0x400, 0x800}; + const TUint32 attrs[] = {EMapAttrSupRw|EMapAttrFullyBlocking, EMapAttrSupRw|EMapAttrCachedMax}; + + __KTRACE_OPT(KPCI, Kern::Printf("Testing PCI access to externally allocated shared chunks")); + for(TInt i=0; i<3; ++i) + { + for(TInt j=0; j<2; ++j) + { + __KTRACE_OPT(KPCI, Kern::Printf("\nSize=0x%08x, attrs=0x%08x", sizes[i], attrs[j])); + TLinAddr virt=NULL; + TUint32 pci=NULL; + TPhysAddr phys=NULL; + DChunk* chunk=NULL; + TInt r = CreateAndMapSC(aFunc, sizes[i], attrs[j], chunk, pci, virt, phys); + TEST_KERRNONE(r); + TestPciMemoryAccess(virt, pci, sizes[i], attrs[j]); + TestAddressConversion(aFunc, pci, phys, sizes[i]); + + r = UnmapAndCloseSC(aFunc, chunk, phys); + TEST_KERRNONE(r); + + } + } + + + } + +DECLARE_STANDARD_EXTENSION() + { + TInt r=KErrNone; + __KTRACE_OPT(KEXTENSION,Kern::Printf("Starting PCI test extension")); + + RArray indicies; + TEST(Pci::Probe(indicies, KNecVendorId, KInternalPciBridgeId) == KErrNotFound); + TEST(Pci::Probe(indicies, KNecVendorId, KExternalPciBridgeId) == KErrNotFound); + + TEST(Pci::Probe(indicies,0x1033, 0x35) == KErrNone); + TEST(indicies.Count()==1); //only expecting one match + const TInt ohciFunc=indicies[0]; + indicies.Close(); + + TAddrSpace& cs = *Pci::GetConfigSpace(ohciFunc); + TAddrSpace& ms = *Pci::GetMemorySpace(ohciFunc); + + TestMemoryAccess(ms); + TestConfigAccess(cs); + TestAllocator(); + TestChunkAllocation(ohciFunc); + TestPciChunkAccesses(ohciFunc); + TestWindowAccesses(ohciFunc); + + __KTRACE_OPT(KPCI, Kern::Printf("DNaviEnginePci: Dumping OHCI config space")); + TUint size=cs.Size(); + for(TUint i=0; i(KHwPciBridgeUsb)[i], i)); + } + return r; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/register.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/register.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,110 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\assp.cpp +* +*/ + + + +#include + +#ifdef __SMP__ +TSpinLock AsspLock(TSpinLock::EOrderGenericIrqLow1); +#endif + +// +// +// MHA - Modular Hardware Adaption +// +// Register Access +// +// + + +// +// We need spin locks around read, modify, write operations because another CPU +// may access the same memory in between operations and potentially cause +// memory corruption. +// +EXPORT_C void AsspRegister::Modify8(TLinAddr aAddr, TUint8 aClearMask, TUint8 aSetMask) + { + TUint irq = __SPIN_LOCK_IRQSAVE(AsspLock); + TUint8 value = *(volatile TUint8 *)aAddr; + value &= ~aClearMask; + value |= aSetMask; + *(volatile TUint8 *)aAddr = value; + __SPIN_UNLOCK_IRQRESTORE(AsspLock,irq); + } + +EXPORT_C void AsspRegister::Modify16(TLinAddr aAddr, TUint16 aClearMask, TUint16 aSetMask) + { + TUint irq = __SPIN_LOCK_IRQSAVE(AsspLock); + TUint16 value = *(volatile TUint16 *)aAddr; + value &= ~aClearMask; + value |= aSetMask; + *(volatile TUint16 *)aAddr = value; + __SPIN_UNLOCK_IRQRESTORE(AsspLock,irq); + } + +EXPORT_C void AsspRegister::Modify32(TLinAddr aAddr, TUint32 aClearMask, TUint32 aSetMask) + { + TUint irq = __SPIN_LOCK_IRQSAVE(AsspLock); + TUint32 value = *(volatile TUint32 *)aAddr; + value &= ~aClearMask; + value |= aSetMask; + *(volatile TUint32 *)aAddr = value; + __SPIN_UNLOCK_IRQRESTORE(AsspLock,irq); + } + +// +// 64 bit operations may be more complex than 8/16/32 bit operations, depending +// upon hardware support for 64 bit accesses. +// +// For example, one platform required an assembly language function to prevent +// the compliler optimising the accesses into 2 x 32 bit accesses and causing a +// bus error. +// +// Spinlocks are required for non-atomic operations and are therefore +// recommended for 64 bit accesses on current platforms. +// +extern TUint64 DoRead64(TLinAddr aAddr); + +EXPORT_C TUint64 AsspRegister::Read64(TLinAddr aAddr) + { + TUint irq = __SPIN_LOCK_IRQSAVE(AsspLock); + TUint64 value = DoRead64(aAddr); + __SPIN_UNLOCK_IRQRESTORE(AsspLock,irq); + return value; + } + +extern void DoWrite64(TLinAddr aAddr, TUint64 aValue); + +EXPORT_C void AsspRegister::Write64(TLinAddr aAddr, TUint64 aValue) + { + TUint irq = __SPIN_LOCK_IRQSAVE(AsspLock); + DoWrite64(aAddr, aValue); + __SPIN_UNLOCK_IRQRESTORE(AsspLock,irq); + } + +EXPORT_C void AsspRegister::Modify64(TLinAddr aAddr, TUint64 aClearMask, TUint64 aSetMask) + { + TUint irq = __SPIN_LOCK_IRQSAVE(AsspLock); + TUint64 value = DoRead64(aAddr); + value &= ~aClearMask; + value |= aSetMask; + DoWrite64(aAddr, value); + __SPIN_UNLOCK_IRQRESTORE(AsspLock,irq); + } + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/staticextension.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/staticextension.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +#include + +#ifdef __USE_GPIO_STATIC_EXTENSION__ +// test standard extension handler number. *DO NOT USE* +#define KTestStaticExtension 0x80000000 +#include +#endif + +#include + +EXPORT_C TInt GPIO::StaticExtension(TInt /*aId*/, TInt aCmd, TAny* /*aArg1*/, TAny* /*aArg2*/) + { + TInt k; + switch (aCmd) + { + case ETestStaticExtension: + k = KErrNone; + break; + default: + k = KErrNotSupported; + break; + } + return k; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/staticextension.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/staticextension.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,27 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// os\boardsupport\naviengine\navienginebsp\ne1_tb\inc\staticextension.h +// +// + +#ifndef __STATICEXTENSION_H__ +#define __STATICEXTENSION_H__ + +enum TStaticExtenstionHandlers + { + ETestStaticExtension = KTestStaticExtension + }; + +#endif /*__STATICEXTENSION_H__*/ + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/traces_usbcc/OstTraceDefinitions.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/traces_usbcc/OstTraceDefinitions.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,24 @@ +// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +// + + +#ifndef __OSTTRACEDEFINITIONS_H__ +#define __OSTTRACEDEFINITIONS_H__ +// OST_TRACE_COMPILER_IN_USE flag has been added by Trace Compiler +// REMOVE BEFORE CHECK-IN TO VERSION CONTROL +// #define OST_TRACE_COMPILER_IN_USE +#include +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/traces_usbcc/fixed_id.definitions --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/traces_usbcc/fixed_id.definitions Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,767 @@ +#Fixed group and trace id definitions. If this file is removed, the identifiers are rebuilt. +[GROUP]TRACE_FATAL=0x81 +[GROUP]TRACE_FLOW=0x8a +[GROUP]TRACE_NORMAL=0x86 +[TRACE]TRACE_FATAL[0x81]_DUP1_TUSBCCONFIGDESCRIPTOR_CONSTRUCT_DUP1=0x43 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_ACTIVATEHARDWARECONTROLLER_DUP2=0xe7 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_ACTIVATEHARDWARECONTROLLER_DUP3=0xe8 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CABLESTATUSTIMERCALLBACK_DUP1=0xfa +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CANCELREADBUFFER_DUP1=0xaa +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CANCELWRITEBUFFER_DUP1=0xab +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CHANGECONFIGURATION_DUP3=0x3f +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CHECKEPAVAILABILITY_DUP1=0xd2 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CREATEENDPOINTS_DUP1=0xda +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CREATEENDPOINTS_DUP2=0xdb +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CREATEENDPOINTS_DUP3=0xdc +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CREATEENDPOINTS_DUP4=0xdd +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CREATEENDPOINTS_DUP5=0xde +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CREATEENDPOINTS_DUP6=0xdf +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CREATEINTERFACE_DUP1=0xd3 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CREATEINTERFACE_DUP10=0xd9 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CREATEINTERFACE_DUP3=0xd4 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CREATEINTERFACE_DUP5=0xd5 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CREATEINTERFACE_DUP6=0xd6 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CREATEINTERFACE_DUP8=0xd7 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_CREATEINTERFACE_DUP9=0xd8 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_DEACTIVATEHARDWARECONTROLLER_DUP2=0xe9 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_DELETEINTERFACESET_DUP1=0xea +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_DELETEINTERFACESET_DUP2=0xeb +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_DELETEINTERFACE_DUP1=0xec +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_DELETEINTERFACE_DUP2=0xed +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_DISABLECLIENTSTACK_DUP2=0x8d +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_ENABLECLIENTSTACK_DUP2=0x8e +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_ENABLECLIENTSTACK_DUP3=0x8f +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_ENDPOINTPACKETSIZE_DUP1=0xcc +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_ENDPOINTPACKETSIZE_DUP4=0xcd +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_EPSTATUSNOTIFY_DUP1=0xee +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_EPSTATUSNOTIFY_DUP3=0xef +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_EPSTATUSNOTIFY_DUP4=0xf0 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_EPSTATUSNOTIFY_DUP5=0xf1 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_EVALUATEOTGCONNECTFLAGS_DUP3=0xf7 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_EVALUATEOTGCONNECTFLAGS_DUP6=0xf8 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_GETCSENDPOINTDESCRIPTORBLOCKSIZE_DUP1=0xca +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_GETCSENDPOINTDESCRIPTORBLOCKSIZE_DUP2=0xcb +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_GETCSENDPOINTDESCRIPTORBLOCK_DUP1=0xc7 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_GETCSINTERFACEDESCRIPTORBLOCKSIZE_DUP1=0xc5 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_GETCSINTERFACEDESCRIPTORBLOCKSIZE_DUP2=0xc6 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_GETCSINTERFACEDESCRIPTORBLOCK_DUP1=0xc2 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_GETENDPOINTDESCRIPTORSIZE_DUP1=0xc0 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_GETENDPOINTDESCRIPTORSIZE_DUP2=0xc1 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_GETENDPOINTDESCRIPTOR_DUP1=0xbe +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_GETINTERFACEDESCRIPTORSIZE_DUP1=0xbd +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_GETINTERFACEDESCRIPTOR_DUP1=0xb4 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_GETINTERFACENUMBER_DUP1=0x9a +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_GETINTERFACENUMBER_DUP2=0x9b +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_HANDLEHNPREQUEST_DUP1=0xd0 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_HANDLEHNPREQUEST_DUP2=0xd1 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_INITIALISEBASECLASS_DUP3=0xcf +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_INTERFACESETTEARDOWN_DUP3=0x41 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_INTERFACESETTEARDOWN_DUP4=0x42 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_INTERFACESETUP_DUP3=0x40 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_NEXTDEVICESTATE_DUP2=0xf2 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_NEXTDEVICESTATE_DUP3=0xf3 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_POWERDOWNDFC_DUP1=0xfc +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_POWERUPDFC_DUP1=0xfb +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_POWERUPUDC_DUP3=0x97 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSCABLEINSERTEVENT_DUP1=0xf5 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSCABLEREMOVEEVENT_DUP1=0xf6 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0DATARECEIVED_DUP2=0xf +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0DATARECEIVED_DUP3=0x10 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0DATARECEIVED_DUP4=0x11 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP13=0x2 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP21=0x3 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP22=0x4 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP26=0x5 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP27=0x6 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP36=0x7 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP37=0x8 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP38=0x9 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP40=0xa +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP41=0xb +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP42=0xc +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP44=0xd +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP48=0xe +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSEP0TRANSMITDONE_DUP1=0x1 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSGETCONFIGURATION_DUP1=0x30 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSGETCONFIGURATION_DUP2=0x31 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSGETCONFIGURATION_DUP3=0x32 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSGETDESCRIPTOR_DUP1=0x2d +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSGETDESCRIPTOR_DUP4=0x2e +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSGETDEVICESTATUS_DUP1=0x12 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSGETENDPOINTSTATUS_DUP1=0x15 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSGETENDPOINTSTATUS_DUP2=0x16 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSGETINTERFACESTATUS_DUP1=0x13 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSGETINTERFACESTATUS_DUP2=0x14 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSGETINTERFACE_DUP1=0x35 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSGETINTERFACE_DUP2=0x36 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSGETINTERFACE_DUP3=0x37 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSRESETEVENT_DUP5=0xf4 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETADDRESS_DUP1=0x2b +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETADDRESS_DUP2=0x2c +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARDEVFEATURE_DUP1=0x17 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARDEVFEATURE_DUP10=0x20 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARDEVFEATURE_DUP11=0x21 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARDEVFEATURE_DUP12=0x22 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARDEVFEATURE_DUP13=0x23 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARDEVFEATURE_DUP14=0x24 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARDEVFEATURE_DUP15=0x25 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARDEVFEATURE_DUP2=0x18 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARDEVFEATURE_DUP3=0x19 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARDEVFEATURE_DUP4=0x1a +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARDEVFEATURE_DUP5=0x1b +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARDEVFEATURE_DUP6=0x1c +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARDEVFEATURE_DUP7=0x1d +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARDEVFEATURE_DUP8=0x1e +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARDEVFEATURE_DUP9=0x1f +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEAREPFEATURE_DUP1=0x27 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEAREPFEATURE_DUP2=0x28 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEAREPFEATURE_DUP3=0x29 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEAREPFEATURE_DUP4=0x2a +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARIFCFEATURE_DUP1=0x26 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCONFIGURATION_DUP1=0x33 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETCONFIGURATION_DUP2=0x34 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETDESCRIPTOR_DUP1=0x2f +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETINTERFACE_DUP1=0x38 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETINTERFACE_DUP2=0x39 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETINTERFACE_DUP3=0x3a +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSETINTERFACE_DUP4=0x3b +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSYNCHFRAME_DUP1=0x3c +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSYNCHFRAME_DUP2=0x3d +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_PROCESSSYNCHFRAME_DUP3=0x3e +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_RECONNECTTIMERCALLBACK_DUP1=0xf9 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_REENUMERATE_DUP3=0x96 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_REGISTERCLIENTCALLBACK_DUP1=0x90 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_REGISTERFORENDPOINTSTATUSCHANGE_DUP1=0x99 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_REGISTERFOROTGFEATURECHANGE_DUP1=0xb3 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_REGISTERFORSTATUSCHANGE_DUP1=0x98 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_REGISTERUDC_DUP1=0xce +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_RELEASEDEVICECONTROL_DUP2=0xae +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_RELEASEDEVICECONTROL_DUP3=0xaf +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETCSENDPOINTDESCRIPTORBLOCK_DUP1=0xc8 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETCSENDPOINTDESCRIPTORBLOCK_DUP2=0xc9 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETCSINTERFACEDESCRIPTORBLOCK_DUP1=0xc3 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETCSINTERFACEDESCRIPTORBLOCK_DUP2=0xc4 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETDEVICECONTROL_DUP1=0xac +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETDEVICECONTROL_DUP2=0xad +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETENDPOINTDESCRIPTOR_DUP1=0xbf +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETENDPOINTZEROMAXPACKETSIZE_DUP1=0xb0 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETINTERFACEDESCRIPTOR_DUP1=0xb5 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETINTERFACEDESCRIPTOR_DUP2=0xb6 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETINTERFACEDESCRIPTOR_DUP3=0xb7 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETINTERFACEDESCRIPTOR_DUP4=0xb8 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETINTERFACEDESCRIPTOR_DUP5=0xb9 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETINTERFACEDESCRIPTOR_DUP6=0xba +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETINTERFACEDESCRIPTOR_DUP7=0xbb +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETINTERFACEDESCRIPTOR_DUP8=0xbc +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETINTERFACE_DUP2=0x92 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETINTERFACE_DUP3=0x93 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETINTERFACE_DUP4=0x94 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETINTERFACE_DUP5=0x95 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETOTGDESCRIPTOR_DUP1=0xb1 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETOTGDESCRIPTOR_DUP3=0xb2 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPIFCDESCRIPTOR_DUP1=0xe0 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPIFCDESCRIPTOR_DUP2=0xe1 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPIFCDESCRIPTOR_DUP3=0xe2 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPIFCDESCRIPTOR_DUP4=0xe3 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPIFCDESCRIPTOR_DUP5=0xe4 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPIFCDESCRIPTOR_DUP6=0xe5 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPIFCDESCRIPTOR_DUP7=0xe6 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPREADBUFFER_DUP13=0xa1 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPREADBUFFER_DUP3=0x9c +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPREADBUFFER_DUP4=0x9d +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPREADBUFFER_DUP5=0x9e +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPREADBUFFER_DUP7=0x9f +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPREADBUFFER_DUP8=0xa0 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPWRITEBUFFER_DUP10=0xa8 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPWRITEBUFFER_DUP11=0xa9 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPWRITEBUFFER_DUP3=0xa2 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPWRITEBUFFER_DUP4=0xa3 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPWRITEBUFFER_DUP5=0xa4 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPWRITEBUFFER_DUP6=0xa5 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPWRITEBUFFER_DUP7=0xa6 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_SETUPWRITEBUFFER_DUP8=0xa7 +[TRACE]TRACE_FATAL[0x81]_DUSBCLIENTCONTROLLER_USBCCONTROLLERPOINTER_DUP1=0x91 +[TRACE]TRACE_FATAL[0x81]_TSGLQUEBASE_DOREMOVE=0xfd +[TRACE]TRACE_FATAL[0x81]_TUSBCCLASSSPECIFICDESCRIPTOR_CONSTRUCT_DUP1=0x48 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_DELETEDESCRIPTORS_DUP1=0x79 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_DELETEDESCRIPTORS_DUP2=0x7a +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_DELETEDESCRIPTORS_DUP8=0x7b +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_DELETEIFCDESCRIPTOR_DUP1=0x5c +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_FINDDESCRIPTOR_DUP1=0x50 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_FINDDESCRIPTOR_DUP12=0x58 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_FINDDESCRIPTOR_DUP13=0x59 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_FINDDESCRIPTOR_DUP2=0x51 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_FINDDESCRIPTOR_DUP3=0x52 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_FINDDESCRIPTOR_DUP4=0x53 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_FINDDESCRIPTOR_DUP5=0x54 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_FINDDESCRIPTOR_DUP6=0x55 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_FINDDESCRIPTOR_DUP7=0x56 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_FINDDESCRIPTOR_DUP8=0x57 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_FINDEPDESCRIPTOR_DUP1=0x76 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_FINDEPDESCRIPTOR_DUP2=0x77 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_FINDEPDESCRIPTOR_DUP3=0x78 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_FINDIFCDESCRIPTOR_DUP1=0x75 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_GETCONFIGURATIONDESCRIPTOR_DUP2=0x7d +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_GETCONFIGURATIONDESCRIPTOR_DUP5=0x7e +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_GETCONFIGURATIONDESCRIPTOR_DUP6=0x7f +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_GETCSENDPOINTDESCRIPTORSIZE=0x6b +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_GETCSENDPOINTDESCRIPTORTC=0x69 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_GETCSINTERFACEDESCRIPTORSIZE=0x68 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_GETCSINTERFACEDESCRIPTORTC=0x66 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_GETDEVICEQUALIFIERDESCRIPTORTC_DUP1=0x62 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_GETENDPOINTDESCRIPTORSIZE_DUP1=0x61 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_GETENDPOINTDESCRIPTORTC_DUP1=0x5f +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_GETINTERFACEDESCRIPTORTC_DUP1=0x5d +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_GETOTHERSPEEDCONFIGURATIONDESCRIPTORTC_DUP1=0x64 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_INITHS_DUP2=0x4e +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_INITHS_DUP3=0x4f +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_INIT_DUP1=0x4c +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_INIT_DUP3=0x4d +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_INSERTEPDESC_DUP1=0x74 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETCONFIGURATIONSTRINGDESCRIPTORTC=0x6c +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETCONFIGURATIONSTRINGDESCRIPTORTC_DUP1=0x6d +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETCONFIGURATIONSTRINGDESCRIPTORTC_DUP2=0x6e +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETCONFIGURATIONSTRINGDESCRIPTORTC_DUP3=0x6f +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETCSENDPOINTDESCRIPTORTC=0x6a +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETCSINTERFACEDESCRIPTORTC=0x67 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETDEVICEQUALIFIERDESCRIPTORTC_DUP1=0x63 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETDEVICESTRINGDESCRIPTORTC_DUP1=0x80 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETDEVICESTRINGDESCRIPTORTC_DUP2=0x81 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETDEVICESTRINGDESCRIPTORTC_DUP3=0x82 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETDEVICESTRINGDESCRIPTORTC_DUP4=0x83 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETENDPOINTDESCRIPTORTC_DUP1=0x60 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETIFCSTRINGDESCRIPTOR_DUP1=0x5a +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETIFCSTRINGDESCRIPTOR_DUP2=0x5b +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETINTERFACEDESCRIPTOR_DUP1=0x5e +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETOTHERSPEEDCONFIGURATIONDESCRIPTORTC_DUP1=0x65 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETSTRINGDESCRIPTORTC_DUP1=0x70 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETSTRINGDESCRIPTORTC_DUP2=0x71 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETSTRINGDESCRIPTORTC_DUP3=0x72 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_SETSTRINGDESCRIPTORTC_DUP4=0x73 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_STRINGDESCRIPTOREXISTS_DUP1=0x84 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_STRINGDESCRIPTOREXISTS_DUP2=0x85 +[TRACE]TRACE_FATAL[0x81]_TUSBCDESCRIPTORPOOL_UPDATECONFIGDESCRIPTORNUMIFCS_DUP2=0x7c +[TRACE]TRACE_FATAL[0x81]_TUSBCENDPOINTDESCRIPTORBASE_CONSTRUCT_DUP1=0x44 +[TRACE]TRACE_FATAL[0x81]_TUSBCENDPOINTDESCRIPTORBASE_CONSTRUCT_DUP4=0x45 +[TRACE]TRACE_FATAL[0x81]_TUSBCENDPOINTDESCRIPTORBASE_CONSTRUCT_DUP5=0x46 +[TRACE]TRACE_FATAL[0x81]_TUSBCENDPOINTDESCRIPTORBASE_CONSTRUCT_DUP6=0x47 +[TRACE]TRACE_FATAL[0x81]_TUSBCENDPOINTINFO_ADJUSTEPSIZES=0x86 +[TRACE]TRACE_FATAL[0x81]_TUSBCENDPOINTINFO_ADJUSTEPSIZES_DUP1=0x87 +[TRACE]TRACE_FATAL[0x81]_TUSBCLOGICALENDPOINT_TUSBCLOGICALENDPOINT_CONS_DUP1=0x8a +[TRACE]TRACE_FATAL[0x81]_TUSBCLOGICALENDPOINT_TUSBCLOGICALENDPOINT_CONS_DUP3=0x8b +[TRACE]TRACE_FATAL[0x81]_TUSBCLOGICALENDPOINT_TUSBCLOGICALENDPOINT_CONS_DUP5=0x8c +[TRACE]TRACE_FATAL[0x81]_TUSBCPHYSICALENDPOINT_DIRAVAILABLE_DUP1=0x89 +[TRACE]TRACE_FATAL[0x81]_TUSBCPHYSICALENDPOINT_TYPEAVAILABLE_DUP1=0x88 +[TRACE]TRACE_FATAL[0x81]_TUSBCSTRINGDESCRIPTORBASE_SETWORD=0x4a +[TRACE]TRACE_FATAL[0x81]_TUSBCSTRINGDESCRIPTORBASE_WORD=0x49 +[TRACE]TRACE_FATAL[0x81]_TUSBCSTRINGDESCRIPTOR_CONSTRUCT_DUP1=0x4b +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_ACTIVATEHARDWARECONTROLLER=0xc6 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_ALLOCATEENDPOINTRESOURCE=0xb0 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_CABLEDETECTWITHOUTPOWERCAPS=0xb9 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_CABLESTATUSTIMERCALLBACK=0xda +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_CHANGECONFIGURATION=0x14 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_CHANGEINTERFACE=0x17 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_CHECKEPAVAILABILITY=0xc3 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_CLEARHALTFEATURE=0x13 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_CREATEENDPOINTS=0xc4 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_CURRENTLYUSINGHIGHSPEED=0xb3 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DEACTIVATEHARDWARECONTROLLER=0xc7 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DEALLOCATEENDPOINTRESOURCE=0xb1 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DELETEREQUESTCALLBACK=0xc8 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DELETEREQUESTCALLBACKS=0xc9 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DEREGISTERCLIENTCALLBACK=0xc2 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DEREGISTERFORENDPOINTSTATUSCHANGE=0x86 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DEREGISTERFOROTGFEATURECHANGE=0x9c +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DEREGISTERFORSTATUSCHANGE=0x84 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DEVICECAPS=0x7d +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DEVICEEVENTNOTIFICATION=0xb7 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DEVICEHIGHSPEEDCAPS=0xba +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DEVICEHNPHANDLEDBYHARDWARECAPS=0xbc +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DEVICERESOURCEALLOCV2CAPS=0xbb +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DISABLECLIENTSTACK=0x77 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DOFOREVERYENDPOINTINUSE=0x18 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DUSBCLIENTCONTROLLER_CONS=0xb6 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_DUSBCLIENTCONTROLLER_DES=0x76 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_ENABLECLIENTSTACK=0x78 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_ENDPOINTCAPS=0x7c +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_ENDPOINTZEROMAXPACKETSIZES=0x90 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_ENTERFULLSPEED=0xd6 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_ENTERHIGHSPEED=0xd7 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_EP0STALL=0x88 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_EPSTATUSNOTIFY=0xcb +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_EVALUATEOTGCONNECTFLAGS=0xd8 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETCONFIGURATIONDESCRIPTOR=0x94 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETCONFIGURATIONDESCRIPTORSIZE=0x96 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETCONFIGURATIONSTRINGDESCRIPTOR=0xad +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETCURRENTOTGFEATURES=0x9a +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETDEVICEDESCRIPTOR=0x91 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETDEVICEDESCRIPTORSIZE=0x93 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETDEVICEQUALIFIERDESCRIPTOR=0x9e +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETDEVICESTATUS=0x8a +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETENDPOINTSTATUS=0x8b +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETINTERFACEDESCRIPTORSIZE=0x9d +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETINTERFACENUMBER=0x87 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETMANUFACTURERSTRINGDESCRIPTOR=0xa4 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETOTGDESCRIPTOR=0x97 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETOTGFEATURES=0x99 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETOTHERSPEEDCONFIGURATIONDESCRIPTOR=0xa0 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETPRODUCTSTRINGDESCRIPTOR=0xa7 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETSERIALNUMBERSTRINGDESCRIPTOR=0xaa +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_GETSTRINGDESCRIPTORLANGID=0xa2 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_INITIALISEBASECLASS=0xb5 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_INTERFACESETTEARDOWN=0x16 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_INTERFACESETUP=0x15 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_ISACTIVE=0x79 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_MOVETOADDRESSSTATE=0xb8 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_NEXTDEVICESTATE=0xcf +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_OTGDISABLEUDC=0xc1 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_OTGENABLEUDC=0xc0 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_OTGFEATURESNOTIFY=0xcc +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_POWERDOWN=0xbe +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_POWERDOWNDFC=0xdc +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_POWERDOWNWHENACTIVE=0xbd +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_POWERUP=0xbf +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_POWERUPDFC=0xdb +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_POWERUPUDC=0x80 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCEEDSETDESCRIPTOR=0x11 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSCABLEINSERTEVENT=0xd4 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSCABLEREMOVEEVENT=0xd5 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSDATATRANSFERDONE=0xce +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSEP0DATARECEIVED=0x2 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED=0x1 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSGETCONFIGURATION=0xc +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSGETDESCRIPTOR=0xa +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSGETDEVICESTATUS=0x3 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSGETENDPOINTSTATUS=0x5 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSGETINTERFACE=0xe +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSGETINTERFACESTATUS=0x4 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSRESETEVENT=0xd3 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSRESUMEEVENT=0xd2 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSSETADDRESS=0x9 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARDEVFEATURE=0x6 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSSETCLEAREPFEATURE=0x8 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSSETCLEARIFCFEATURE=0x7 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSSETCONFIGURATION=0xd +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSSETDESCRIPTOR=0xb +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSSETINTERFACE=0xf +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSSUSPENDEVENT=0xd0 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSSUSPENDEVENTPROCEED=0xd1 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_PROCESSSYNCHFRAME=0x10 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_QUERYENDPOINTRESOURCE=0xb2 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_RECONNECTTIMERCALLBACK=0xd9 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_REENUMERATE=0x7f +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_REGISTERCLIENTCALLBACK=0x7a +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_REGISTERFORENDPOINTSTATUSCHANGE=0x85 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_REGISTERFOROTGFEATURECHANGE=0x9b +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_REGISTERFORSTATUSCHANGE=0x83 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_REGISTERUDC=0xb4 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_RELEASEDEVICECONTROL=0x8f +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_REMOVECONFIGURATIONSTRINGDESCRIPTOR=0xaf +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_REMOVEMANUFACTURERSTRINGDESCRIPTOR=0xa6 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_REMOVEPRODUCTSTRINGDESCRIPTOR=0xa9 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_REMOVESERIALNUMBERSTRINGDESCRIPTOR=0xac +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_RUNCLIENTCALLBACKS=0xcd +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SENDEP0STATUSPACKET=0x89 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SETCLEARHALTFEATURE=0x12 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SETCONFIGURATIONDESCRIPTOR=0x95 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SETCONFIGURATIONSTRINGDESCRIPTOR=0xae +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SETDEVICECONTROL=0x8e +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SETDEVICEDESCRIPTOR=0x92 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SETDEVICEQUALIFIERDESCRIPTOR=0x9f +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SETINTERFACE=0x7e +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SETMANUFACTURERSTRINGDESCRIPTOR=0xa5 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SETOTGDESCRIPTOR=0x98 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SETOTHERSPEEDCONFIGURATIONDESCRIPTOR=0xa1 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SETPRODUCTSTRINGDESCRIPTOR=0xa8 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SETSERIALNUMBERSTRINGDESCRIPTOR=0xab +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SETSTRINGDESCRIPTORLANGID=0xa3 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SETUPIFCDESCRIPTOR=0xc5 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SETUPREADBUFFER=0x8c +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_SETUPWRITEBUFFER=0x8d +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_STATUSNOTIFY=0xca +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_USBCCONTROLLERPOINTER=0x7b +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_USBCONNECT=0x81 +[TRACE]TRACE_FLOW[0x8A]_DUSBCLIENTCONTROLLER_USBDISCONNECT=0x82 +[TRACE]TRACE_FLOW[0x8A]_TUSBCAUDIOENDPOINTDESCRIPTOR_CONSTRUCT=0x34 +[TRACE]TRACE_FLOW[0x8A]_TUSBCAUDIOENDPOINTDESCRIPTOR_NEW=0x33 +[TRACE]TRACE_FLOW[0x8A]_TUSBCAUDIOENDPOINTDESCRIPTOR_TUSBCAUDIOENDPOINTDESCRIPTOR_CONS=0x32 +[TRACE]TRACE_FLOW[0x8A]_TUSBCCLASSSPECIFICDESCRIPTOR_CONSTRUCT=0x3b +[TRACE]TRACE_FLOW[0x8A]_TUSBCCLASSSPECIFICDESCRIPTOR_NEW=0x3a +[TRACE]TRACE_FLOW[0x8A]_TUSBCCLASSSPECIFICDESCRIPTOR_TUSBCCLASSSPECIFICDESCRIPTOR_CONS=0x38 +[TRACE]TRACE_FLOW[0x8A]_TUSBCCLASSSPECIFICDESCRIPTOR_TUSBCCLASSSPECIFICDESCRIPTOR_DES=0x39 +[TRACE]TRACE_FLOW[0x8A]_TUSBCCONFIGDESCRIPTOR_CONSTRUCT=0x27 +[TRACE]TRACE_FLOW[0x8A]_TUSBCCONFIGDESCRIPTOR_NEW=0x26 +[TRACE]TRACE_FLOW[0x8A]_TUSBCCONFIGDESCRIPTOR_TUSBCCONFIGDESCRIPTOR_CONS=0x25 +[TRACE]TRACE_FLOW[0x8A]_TUSBCCONFIGURATION_TUSBCCONFIGURATION_CONS=0x74 +[TRACE]TRACE_FLOW[0x8A]_TUSBCCONFIGURATION_TUSBCCONFIGURATION_DES=0x75 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORBASE_TUSBCDESCRIPTORBASE_CONS=0x19 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORBASE_TUSBCDESCRIPTORBASE_DES=0x1a +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_DELETEDESCRIPTORS=0x61 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_EXCHANGESTRINGDESCRIPTOR=0x67 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_FINDAVAILABLESTRINGPOS=0x69 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_FINDDESCRIPTOR=0x4c +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_GETCONFIGURATIONDESCRIPTORTC=0x50 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_GETDEVICEDESCRIPTOR=0x62 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_GETDEVICEDESCRIPTORTC=0x4e +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_GETDEVICEQUALIFIERDESCRIPTORTC=0x57 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_GETDEVICESTRINGDESCRIPTORTC=0x64 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_GETENDPOINTDESCRIPTORSIZE=0x56 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_GETENDPOINTDESCRIPTORTC=0x54 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_GETINTERFACEDESCRIPTORTC=0x52 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_GETOTGDESCRIPTOR=0x63 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_GETOTHERSPEEDCONFIGURATIONDESCRIPTORTC=0x59 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_GETSTRINGDESCRIPTORTC=0x5b +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_GETSTRINGDESCRIPTORTC_DUP1=0x5c +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_INIT=0x48 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_INITHS=0x49 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_INSERTDESCRIPTOR=0x4d +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_INSERTEPDESC=0x60 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_INSERTIFCDESC=0x5f +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_REMOVEDEVICESTRINGDESCRIPTOR=0x66 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_REMOVESTRINGDESCRIPTOR=0x5e +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_SETCONFIGURATIONDESCRIPTORTC=0x51 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_SETDEVICEDESCRIPTORTC=0x4f +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_SETDEVICEQUALIFIERDESCRIPTORTC=0x58 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_SETDEVICESTRINGDESCRIPTORTC=0x65 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_SETENDPOINTDESCRIPTORTC=0x55 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_SETINTERFACEDESCRIPTOR=0x53 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_SETOTHERSPEEDCONFIGURATIONDESCRIPTORTC=0x5a +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_SETSTRINGDESCRIPTORTC=0x5d +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_STRINGDESCRIPTOREXISTS=0x68 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_TUSBCDESCRIPTORPOOL_CONS=0x46 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_TUSBCDESCRIPTORPOOL_DES=0x47 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_UPDATEDESCRIPTORSFS=0x4a +[TRACE]TRACE_FLOW[0x8A]_TUSBCDESCRIPTORPOOL_UPDATEDESCRIPTORSHS=0x4b +[TRACE]TRACE_FLOW[0x8A]_TUSBCDEVICEDESCRIPTOR_CONSTRUCT=0x1d +[TRACE]TRACE_FLOW[0x8A]_TUSBCDEVICEDESCRIPTOR_NEW=0x1c +[TRACE]TRACE_FLOW[0x8A]_TUSBCDEVICEDESCRIPTOR_TUSBCDEVICEDESCRIPTOR_CONS=0x1b +[TRACE]TRACE_FLOW[0x8A]_TUSBCDEVICEDESCRIPTOR_UPDATEFS=0x1e +[TRACE]TRACE_FLOW[0x8A]_TUSBCDEVICEDESCRIPTOR_UPDATEHS=0x1f +[TRACE]TRACE_FLOW[0x8A]_TUSBCDEVICEQUALIFIERDESCRIPTOR_CONSTRUCT=0x22 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDEVICEQUALIFIERDESCRIPTOR_NEW=0x21 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDEVICEQUALIFIERDESCRIPTOR_TUSBCDEVICEQUALIFIERDESCRIPTOR_CONS=0x20 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDEVICEQUALIFIERDESCRIPTOR_UPDATEFS=0x23 +[TRACE]TRACE_FLOW[0x8A]_TUSBCDEVICEQUALIFIERDESCRIPTOR_UPDATEHS=0x24 +[TRACE]TRACE_FLOW[0x8A]_TUSBCENDPOINTDESCRIPTORBASE_CONSTRUCT=0x2c +[TRACE]TRACE_FLOW[0x8A]_TUSBCENDPOINTDESCRIPTORBASE_TUSBCENDPOINTDESCRIPTORBASE_CONS=0x2b +[TRACE]TRACE_FLOW[0x8A]_TUSBCENDPOINTDESCRIPTORBASE_UPDATEFS=0x2d +[TRACE]TRACE_FLOW[0x8A]_TUSBCENDPOINTDESCRIPTORBASE_UPDATEHS=0x2e +[TRACE]TRACE_FLOW[0x8A]_TUSBCENDPOINTDESCRIPTOR_CONSTRUCT=0x31 +[TRACE]TRACE_FLOW[0x8A]_TUSBCENDPOINTDESCRIPTOR_NEW=0x30 +[TRACE]TRACE_FLOW[0x8A]_TUSBCENDPOINTDESCRIPTOR_TUSBCENDPOINTDESCRIPTOR_CONS=0x2f +[TRACE]TRACE_FLOW[0x8A]_TUSBCINTERFACEDESCRIPTOR_CONSTRUCT=0x2a +[TRACE]TRACE_FLOW[0x8A]_TUSBCINTERFACEDESCRIPTOR_NEW=0x29 +[TRACE]TRACE_FLOW[0x8A]_TUSBCINTERFACEDESCRIPTOR_TUSBCINTERFACEDESCRIPTOR_CONS=0x28 +[TRACE]TRACE_FLOW[0x8A]_TUSBCINTERFACESET_TUSBCINTERFACESET_CONS=0x72 +[TRACE]TRACE_FLOW[0x8A]_TUSBCINTERFACESET_TUSBCINTERFACESET_DES=0x73 +[TRACE]TRACE_FLOW[0x8A]_TUSBCINTERFACE_TUSBCINTERFACE_CONS=0x70 +[TRACE]TRACE_FLOW[0x8A]_TUSBCINTERFACE_TUSBCINTERFACE_DES=0x71 +[TRACE]TRACE_FLOW[0x8A]_TUSBCLANGIDDESCRIPTOR_CONSTRUCT=0x45 +[TRACE]TRACE_FLOW[0x8A]_TUSBCLANGIDDESCRIPTOR_NEW=0x44 +[TRACE]TRACE_FLOW[0x8A]_TUSBCLANGIDDESCRIPTOR_TUSBCLANGIDDESCRIPTOR_CONS=0x42 +[TRACE]TRACE_FLOW[0x8A]_TUSBCLANGIDDESCRIPTOR_TUSBCLANGIDDESCRIPTOR_DES=0x43 +[TRACE]TRACE_FLOW[0x8A]_TUSBCLOGICALENDPOINT_TUSBCLOGICALENDPOINT_CONS=0x6f +[TRACE]TRACE_FLOW[0x8A]_TUSBCOTGDESCRIPTOR_CONSTRUCT=0x37 +[TRACE]TRACE_FLOW[0x8A]_TUSBCOTGDESCRIPTOR_NEW=0x35 +[TRACE]TRACE_FLOW[0x8A]_TUSBCOTGDESCRIPTOR_TUSBCOTGDESCRIPTOR_CONS=0x36 +[TRACE]TRACE_FLOW[0x8A]_TUSBCPHYSICALENDPOINT_DIRAVAILABLE=0x6c +[TRACE]TRACE_FLOW[0x8A]_TUSBCPHYSICALENDPOINT_ENDPOINTSUITABLE=0x6d +[TRACE]TRACE_FLOW[0x8A]_TUSBCPHYSICALENDPOINT_TUSBCPHYSICALENDPOINT_CONS=0x6a +[TRACE]TRACE_FLOW[0x8A]_TUSBCPHYSICALENDPOINT_TUSBCPHYSICALENDPOINT_DES=0x6e +[TRACE]TRACE_FLOW[0x8A]_TUSBCPHYSICALENDPOINT_TYPEAVAILABLE=0x6b +[TRACE]TRACE_FLOW[0x8A]_TUSBCSTRINGDESCRIPTORBASE_TUSBCSTRINGDESCRIPTORBASE_CONS=0x3c +[TRACE]TRACE_FLOW[0x8A]_TUSBCSTRINGDESCRIPTORBASE_TUSBCSTRINGDESCRIPTORBASE_DES=0x3d +[TRACE]TRACE_FLOW[0x8A]_TUSBCSTRINGDESCRIPTOR_CONSTRUCT=0x41 +[TRACE]TRACE_FLOW[0x8A]_TUSBCSTRINGDESCRIPTOR_NEW=0x40 +[TRACE]TRACE_FLOW[0x8A]_TUSBCSTRINGDESCRIPTOR_TUSBCSTRINGDESCRIPTOR_CONS=0x3e +[TRACE]TRACE_FLOW[0x8A]_TUSBCSTRINGDESCRIPTOR_TUSBCSTRINGDESCRIPTOR_DES=0x3f +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_ACTIVATEHARDWARECONTROLLER_DUP1=0x100 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_ACTIVATEHARDWARECONTROLLER_DUP4=0x101 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CANCELREADBUFFER=0xbc +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CANCELTRANSFERREQUESTS=0x107 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CANCELWRITEBUFFER=0xbd +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CHANGECONFIGURATION_DUP1=0x3e +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CHANGECONFIGURATION_DUP2=0x3f +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CHANGECONFIGURATION_DUP4=0x40 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CHANGECONFIGURATION_DUP5=0x41 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CHANGECONFIGURATION_DUP6=0x42 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CHANGECONFIGURATION_DUP7=0x43 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CHANGECONFIGURATION_DUP8=0x44 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CHANGECONFIGURATION_DUP9=0x45 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CHANGEINTERFACE_DUP1=0x4d +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CHANGEINTERFACE_DUP2=0x4e +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CHECKEPAVAILABILITY_DUP2=0xf2 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CHECKEPAVAILABILITY_DUP3=0xf3 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CHECKEPAVAILABILITY_DUP4=0xf4 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CLEARHALTENDPOINT=0xbf +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CLOSEDMACHANNEL=0xee +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CREATEENDPOINTS_DUP10=0xfc +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CREATEENDPOINTS_DUP11=0xfd +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CREATEENDPOINTS_DUP12=0xfe +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CREATEENDPOINTS_DUP13=0xff +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CREATEENDPOINTS_DUP7=0xf9 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CREATEENDPOINTS_DUP8=0xfa +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CREATEENDPOINTS_DUP9=0xfb +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CREATEINTERFACE=0xf5 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CREATEINTERFACE_DUP2=0xf6 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CREATEINTERFACE_DUP4=0xf7 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_CREATEINTERFACE_DUP7=0xf8 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DEACTIVATEHARDWARECONTROLLER_DUP1=0x102 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DEACTIVATEHARDWARECONTROLLER_DUP3=0x103 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DELETEINTERFACE=0x105 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DELETEINTERFACESET=0x104 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DELETEINTERFACE_DUP3=0x106 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DELETEREQUESTCALLBACKS_DUP1=0x10a +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DELETEREQUESTCALLBACKS_DUP2=0x10b +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DELETEREQUESTCALLBACK_DUP1=0x108 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DELETEREQUESTCALLBACK_DUP2=0x109 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DEREGISTERCLIENT=0xae +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DEREGISTERCLIENTCALLBACK_DUP1=0xf0 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DEREGISTERCLIENTCALLBACK_DUP2=0xf1 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DEREGISTERCLIENT_DUP1=0xaf +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DEREGISTERFORENDPOINTSTATUSCHANGE_DUP1=0xac +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DEREGISTERFORENDPOINTSTATUSCHANGE_DUP2=0xad +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DEREGISTERFOROTGFEATURECHANGE_DUP1=0xca +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DEREGISTERFOROTGFEATURECHANGE_DUP2=0xcb +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DEREGISTERFORSTATUSCHANGE_DUP1=0xa9 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DEREGISTERFORSTATUSCHANGE_DUP2=0xaa +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DISABLECLIENTSTACK_DUP1=0x97 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DOFOREVERYENDPOINTINUSE_DUP1=0x4f +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_DUSBCLIENTCONTROLLER_DES_DUP1=0x96 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_ENABLECLIENTSTACK_DUP1=0x98 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_ENDPOINTCAPS_DUP1=0x9a +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_ENDPOINTCAPS_DUP2=0x9b +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_ENDPOINTPACKETSIZE=0xda +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_ENDPOINTPACKETSIZE_DUP2=0xdb +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_ENDPOINTPACKETSIZE_DUP3=0xdc +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_ENDPOINTREQUESTCOMPLETE=0xe5 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_ENQUIREEP0NEXTSTATE=0x1 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_ENQUIREEP0NEXTSTATE_DUP1=0x2 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_ENQUIREEP0NEXTSTATE_DUP2=0x3 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_ENQUIREEP0NEXTSTATE_DUP3=0x4 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_ENTERTESTMODE=0xef +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EP0PACKETSIZE=0xb0 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EP0PACKETSIZE_DUP1=0xb1 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EP0REQUESTCOMPLETE=0xe7 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EP0REQUESTCOMPLETE_DUP1=0xe8 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EP0REQUESTCOMPLETE_DUP2=0xe9 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EP0REQUESTCOMPLETE_DUP3=0xea +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EP0REQUESTCOMPLETE_DUP4=0xeb +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EPSTATUSNOTIFY_DUP2=0x10d +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EPSTATUSNOTIFY_DUP6=0x10e +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EPSTATUSNOTIFY_DUP7=0x10f +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EPSTATUSNOTIFY_DUP8=0x110 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EPSTATUSNOTIFY_DUP9=0x111 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EVALUATEOTGCONNECTFLAGS_DUP1=0x11b +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EVALUATEOTGCONNECTFLAGS_DUP2=0x11c +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EVALUATEOTGCONNECTFLAGS_DUP4=0x11d +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EVALUATEOTGCONNECTFLAGS_DUP5=0x11e +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_EVALUATEOTGCONNECTFLAGS_DUP7=0x11f +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_GETCSENDPOINTDESCRIPTORBLOCK=0xd4 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_GETCSENDPOINTDESCRIPTORBLOCKSIZE=0xd6 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_GETCSINTERFACEDESCRIPTORBLOCK=0xd1 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_GETCSINTERFACEDESCRIPTORBLOCKSIZE=0xd3 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_GETENDPOINTDESCRIPTOR=0xce +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_GETENDPOINTDESCRIPTORSIZE=0xd0 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_GETINTERFACEDESCRIPTOR=0xcc +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_GETSTRINGDESCRIPTOR=0xd7 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_HALTENDPOINT=0xbe +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_HANDLEHNPREQUEST=0xe6 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_INITIALISEBASECLASS_DUP1=0xdd +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_INITIALISEBASECLASS_DUP2=0xde +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_INITIALISEBASECLASS_DUP4=0xdf +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_INITIALISEBASECLASS_DUP5=0xe0 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_INITIALISEBASECLASS_DUP6=0xe1 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_INITIALISEBASECLASS_DUP7=0xe2 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_INITIALISEBASECLASS_DUP8=0xe3 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_INITIALISEBASECLASS_DUP9=0xe4 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_INTERFACESETTEARDOWN_DUP1=0x49 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_INTERFACESETTEARDOWN_DUP2=0x4a +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_INTERFACESETTEARDOWN_DUP5=0x4b +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_INTERFACESETTEARDOWN_DUP6=0x4c +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_INTERFACESETUP_DUP1=0x46 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_INTERFACESETUP_DUP2=0x47 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_INTERFACESETUP_DUP4=0x48 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_NEXTDEVICESTATE_DUP1=0x114 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_NEXTDEVICESTATE_DUP4=0x115 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_OPENDMACHANNEL=0xed +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_POWERDOWNDFC_DUP2=0x120 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_POWERDOWNDFC_DUP3=0x121 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_POWERDOWNDFC_DUP4=0x122 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_POWERUPUDC_DUP1=0xa5 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_POWERUPUDC_DUP2=0xa6 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSDATATRANSFERDONE_DUP1=0x113 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0DATARECEIVED_DUP1=0x2a +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0DATARECEIVED_DUP5=0x2b +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0DATARECEIVED_DUP6=0x2c +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0RECEIVEDONE=0x5 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP1=0x7 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP10=0x10 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP11=0x11 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP12=0x12 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP14=0x13 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP15=0x14 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP16=0x15 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP17=0x16 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP18=0x17 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP19=0x18 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP2=0x8 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP20=0x19 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP23=0x1a +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP24=0x1b +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP25=0x1c +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP28=0x1d +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP29=0x1e +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP3=0x9 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP30=0x1f +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP31=0x20 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP32=0x21 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP33=0x22 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP34=0x23 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP35=0x24 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP39=0x25 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP4=0xa +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP43=0x26 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP45=0x27 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP46=0x28 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP47=0x29 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP5=0xb +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP6=0xc +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP7=0xd +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP8=0xe +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0SETUPRECEIVED_DUP9=0xf +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSEP0TRANSMITDONE=0x6 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSGETCONFIGURATION_DUP4=0x34 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSGETCONFIGURATION_DUP5=0x35 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSGETDESCRIPTOR_DUP2=0x31 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSGETDESCRIPTOR_DUP3=0x32 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSGETDESCRIPTOR_DUP5=0x33 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSGETDEVICESTATUS_DUP2=0x2d +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSGETENDPOINTSTATUS_DUP3=0x2f +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSGETINTERFACESTATUS_DUP3=0x2e +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSGETINTERFACE_DUP4=0x38 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSRESETEVENT_DUP1=0x117 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSRESETEVENT_DUP2=0x118 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSRESETEVENT_DUP3=0x119 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSRESETEVENT_DUP4=0x11a +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSSETADDRESS_DUP3=0x30 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSSETCONFIGURATION_DUP3=0x36 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSSETCONFIGURATION_DUP4=0x37 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSSETINTERFACE_DUP5=0x39 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_PROCESSSUSPENDEVENTPROCEED_DUP1=0x116 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_REENUMERATE_DUP1=0xa3 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_REENUMERATE_DUP2=0xa4 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_REGISTERCLIENTCALLBACK_DUP2=0x99 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_REGISTERFORENDPOINTSTATUSCHANGE_DUP2=0xab +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_REGISTERFOROTGFEATURECHANGE_DUP2=0xc9 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_REGISTERFORSTATUSCHANGE_DUP2=0xa8 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_RELEASEDEVICECONTROL_DUP1=0xc0 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_RELEASEINTERFACE=0x9d +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_RELEASEINTERFACE_DUP1=0x9e +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_RELEASEINTERFACE_DUP2=0x9f +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_RELEASEINTERFACE_DUP3=0xa0 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_RELEASEINTERFACE_DUP4=0xa1 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_RELEASEINTERFACE_DUP5=0xa2 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_REMOVESTRINGDESCRIPTOR=0xd9 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_RUNCLIENTCALLBACKS_DUP1=0x112 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETCLEARHALTFEATURE_DUP1=0x3a +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETCLEARHALTFEATURE_DUP2=0x3b +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETCLEARHALTFEATURE_DUP3=0x3c +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETCLEARHALTFEATURE_DUP4=0x3d +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETCSENDPOINTDESCRIPTORBLOCK=0xd5 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETCSINTERFACEDESCRIPTORBLOCK=0xd2 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETCURRENT=0xec +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETENDPOINTDESCRIPTOR=0xcf +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETENDPOINTZEROMAXPACKETSIZE=0xc1 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETENDPOINTZEROMAXPACKETSIZE_DUP2=0xc2 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETINTERFACEDESCRIPTOR=0xcd +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETINTERFACE_DUP1=0x9c +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETOTGDESCRIPTOR_DUP2=0xc3 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETOTGDESCRIPTOR_DUP4=0xc4 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETOTGDESCRIPTOR_DUP5=0xc5 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETOTGDESCRIPTOR_DUP6=0xc6 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETOTGDESCRIPTOR_DUP7=0xc7 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETOTGDESCRIPTOR_DUP8=0xc8 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETSTRINGDESCRIPTOR=0xd8 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETUPREADBUFFER_DUP1=0xb2 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETUPREADBUFFER_DUP10=0xb6 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETUPREADBUFFER_DUP11=0xb7 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETUPREADBUFFER_DUP12=0xb8 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETUPREADBUFFER_DUP2=0xb3 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETUPREADBUFFER_DUP6=0xb4 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETUPREADBUFFER_DUP9=0xb5 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETUPWRITEBUFFER_DUP1=0xb9 +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETUPWRITEBUFFER_DUP2=0xba +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_SETUPWRITEBUFFER_DUP9=0xbb +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_STATUSNOTIFY_DUP1=0x10c +[TRACE]TRACE_NORMAL[0x86]_DUSBCLIENTCONTROLLER_USBCONNECT_DUP1=0xa7 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_DELETEDESCRIPTORS_DUP3=0x6f +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_DELETEDESCRIPTORS_DUP4=0x70 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_DELETEDESCRIPTORS_DUP5=0x71 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_DELETEDESCRIPTORS_DUP6=0x72 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_DELETEDESCRIPTORS_DUP7=0x73 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_DELETEIFCDESCRIPTOR=0x5e +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_EXCHANGESTRINGDESCRIPTOR_DUP1=0x87 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_EXCHANGESTRINGDESCRIPTOR_DUP2=0x88 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_FINDAVAILABLESTRINGPOS_DUP1=0x89 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_FINDDESCRIPTOR_DUP10=0x59 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_FINDDESCRIPTOR_DUP11=0x5a +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_FINDDESCRIPTOR_DUP9=0x58 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_FINDEPDESCRIPTOR=0x6e +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_FINDIFCDESCRIPTOR=0x6d +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_GETCONFIGURATIONDESCRIPTOR=0x7d +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_GETCONFIGURATIONDESCRIPTOR_DUP1=0x7e +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_GETCONFIGURATIONDESCRIPTOR_DUP3=0x7f +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_GETCONFIGURATIONDESCRIPTOR_DUP4=0x80 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_GETCONFIGURATIONDESCRIPTOR_DUP7=0x81 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_GETCONFIGURATIONSTRINGDESCRIPTORTC=0x60 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_GETCONFIGURATIONSTRINGDESCRIPTORTC_DUP1=0x61 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_GETDEVICEDESCRIPTOR_DUP1=0x7b +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_GETDEVICEDESCRIPTOR_DUP2=0x7c +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_GETDEVICESTRINGDESCRIPTORTC_DUP1=0x84 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_GETDEVICESTRINGDESCRIPTORTC_DUP2=0x85 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_GETOTGDESCRIPTOR_DUP1=0x82 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_GETSTRINGDESCRIPTOR=0x83 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_INITHS_DUP1=0x57 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_INIT_DUP2=0x54 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_INIT_DUP4=0x55 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_INIT_DUP5=0x56 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_INSERTDESCRIPTOR_DUP1=0x5b +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_INSERTIFCDESC_DUP1=0x6a +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_INSERTIFCDESC_DUP2=0x6b +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_INSERTIFCDESC_DUP3=0x6c +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_REMOVECONFIGURATIONSTRINGDESCRIPTOR=0x62 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_REMOVEDEVICESTRINGDESCRIPTOR_DUP1=0x86 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_REMOVESTRINGDESCRIPTOR_DUP1=0x63 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_REMOVESTRINGDESCRIPTOR_DUP2=0x64 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_REMOVESTRINGDESCRIPTOR_DUP3=0x65 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_REMOVESTRINGDESCRIPTOR_DUP4=0x66 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_REMOVESTRINGDESCRIPTOR_DUP5=0x67 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_REMOVESTRINGDESCRIPTOR_DUP6=0x68 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_REMOVESTRINGDESCRIPTOR_DUP7=0x69 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_SETCSINTERFACEDESCRIPTORTC_DUP1=0x5f +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_SETIFCSTRINGDESCRIPTOR=0x5c +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_SETIFCSTRINGDESCRIPTOR_DUP3=0x5d +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_TUSBCDESCRIPTORPOOL_DES_DUP1=0x52 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_TUSBCDESCRIPTORPOOL_DES_DUP2=0x53 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_UPDATECONFIGDESCRIPTORLENGTH=0x74 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_UPDATECONFIGDESCRIPTORLENGTH_DUP1=0x75 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_UPDATECONFIGDESCRIPTORLENGTH_DUP2=0x76 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_UPDATECONFIGDESCRIPTORNUMIFCS=0x77 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_UPDATECONFIGDESCRIPTORNUMIFCS_DUP1=0x78 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_UPDATECONFIGDESCRIPTORNUMIFCS_DUP3=0x79 +[TRACE]TRACE_NORMAL[0x86]_TUSBCDESCRIPTORPOOL_UPDATEIFCNUMBERS=0x7a +[TRACE]TRACE_NORMAL[0x86]_TUSBCENDPOINTDESCRIPTORBASE_CONSTRUCT_DUP2=0x50 +[TRACE]TRACE_NORMAL[0x86]_TUSBCENDPOINTDESCRIPTORBASE_CONSTRUCT_DUP3=0x51 +[TRACE]TRACE_NORMAL[0x86]_TUSBCLOGICALENDPOINT_TUSBCLOGICALENDPOINT_CONS_DUP2=0x90 +[TRACE]TRACE_NORMAL[0x86]_TUSBCLOGICALENDPOINT_TUSBCLOGICALENDPOINT_CONS_DUP4=0x91 +[TRACE]TRACE_NORMAL[0x86]_TUSBCLOGICALENDPOINT_TUSBCLOGICALENDPOINT_DES=0x92 +[TRACE]TRACE_NORMAL[0x86]_TUSBCLOGICALENDPOINT_TUSBCLOGICALENDPOINT_DES_DUP1=0x93 +[TRACE]TRACE_NORMAL[0x86]_TUSBCLOGICALENDPOINT_TUSBCLOGICALENDPOINT_DES_DUP2=0x94 +[TRACE]TRACE_NORMAL[0x86]_TUSBCLOGICALENDPOINT_TUSBCLOGICALENDPOINT_DES_DUP3=0x95 +[TRACE]TRACE_NORMAL[0x86]_TUSBCPHYSICALENDPOINT_ENDPOINTSUITABLE_DUP1=0x8a +[TRACE]TRACE_NORMAL[0x86]_TUSBCPHYSICALENDPOINT_ENDPOINTSUITABLE_DUP2=0x8b +[TRACE]TRACE_NORMAL[0x86]_TUSBCPHYSICALENDPOINT_ENDPOINTSUITABLE_DUP3=0x8c +[TRACE]TRACE_NORMAL[0x86]_TUSBCPHYSICALENDPOINT_ENDPOINTSUITABLE_DUP4=0x8d +[TRACE]TRACE_NORMAL[0x86]_TUSBCPHYSICALENDPOINT_ENDPOINTSUITABLE_DUP5=0x8e +[TRACE]TRACE_NORMAL[0x86]_TUSBCPHYSICALENDPOINT_ENDPOINTSUITABLE_DUP6=0x8f diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/uart/uart.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/uart/uart.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp/uart/uart.mmp +* +*/ + + + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(euart,pdd) +targettype pdd +romtarget euart.pdd + +USERINCLUDE ../ +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +sourcepath . +source uart16550_ne.cpp uart16550_ne.cia + +library VariantTarget(kanaviengine,lib) VariantTarget(ecust,lib) + +uid 0 0x1000015b + +VENDORID 0x70000001 + +capability all + +SMPSAFE +MACRO CPU_AFFINITY_ANY diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/uart/uart16550_ne.cia --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/uart/uart16550_ne.cia Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,133 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\uart\uart16550.cia +* PDD for 16550 UART - ARM assembler bits +* +*/ + + + +#include +#include +#include "uart16550_ne.h" +#include + +__NAKED__ void T16550Uart::ModifyFCR(TUint /*aClearMask*/, TUint /*aSetMask*/) + { + asm("mrs ip, cpsr "); + asm("orr r3, ip, #0xc0 "); + asm("msr cpsr, r3 "); + asm("ldrb r3, [r0, #4] "); + asm("bic r3, r3, r1 "); + asm("ldr r1, [r0, #0] "); + asm("orr r3, r3, r2 "); + asm("strb r3, [r0, #4] "); + asm("strb r3, [r1, #%a0]" : : "i" ((TInt)K16550FCROffset)); + asm("msr cpsr, ip "); + __JUMP(,lr); + } + +__NAKED__ void T16550Uart::ModifyLCR(TUint /*aClearMask*/, TUint /*aSetMask*/) + { + asm("mrs ip, cpsr "); + asm("orr r3, ip, #0xc0 "); + asm("msr cpsr, r3 "); + asm("ldrb r3, [r0, #5] "); + asm("bic r3, r3, r1 "); + asm("ldr r1, [r0, #0] "); + asm("orr r3, r3, r2 "); + asm("strb r3, [r0, #5] "); + asm("strb r3, [r1, #%a0]" : : "i" ((TInt)K16550LCROffset)); + asm("msr cpsr, ip "); + __JUMP(,lr); + } + +__NAKED__ void T16550Uart::ModifyMCR(TUint /*aClearMask*/, TUint /*aSetMask*/) + { + asm("mrs ip, cpsr "); + asm("orr r3, ip, #0xc0 "); + asm("msr cpsr, r3 "); + asm("ldrb r3, [r0, #6] "); + asm("bic r3, r3, r1 "); + asm("ldr r1, [r0, #0] "); + asm("orr r3, r3, r2 "); + asm("strb r3, [r0, #6] "); + asm("strb r3, [r1, #%a0]" : : "i" ((TInt)K16550MCROffset)); + asm("msr cpsr, ip "); + __JUMP(,lr); + } + +__NAKED__ void T16550Uart::ModifyIER(TUint /*aClearMask*/, TUint /*aSetMask*/) + { + asm("mrs ip, cpsr "); + asm("orr r3, ip, #0xc0 "); + asm("msr cpsr, r3 "); + asm("ldrb r3, [r0, #7] "); + asm("bic r3, r3, r1 "); + asm("ldr r1, [r0, #0] "); + asm("orr r3, r3, r2 "); + asm("strb r3, [r0, #7] "); + asm("strb r3, [r1, #%a0]" : : "i" ((TInt)K16550IEROffset)); + asm("msr cpsr, ip "); + __JUMP(,lr); + } + +__NAKED__ void T16550Uart::SetFCR(TUint /*aValue*/) + { + asm("mrs ip, cpsr "); + asm("ldr r3, [r0, #0] "); + asm("orr r2, ip, #0xc0 "); + asm("msr cpsr, r2 "); + asm("strb r1, [r0, #4] "); + asm("strb r1, [r3, #%a0]" : : "i" ((TInt)K16550FCROffset)); + asm("msr cpsr, ip "); + __JUMP(,lr); + } + +__NAKED__ void T16550Uart::SetLCR(TUint /*aValue*/) + { + asm("mrs ip, cpsr "); + asm("ldr r3, [r0, #0] "); + asm("orr r2, ip, #0xc0 "); + asm("msr cpsr, r2 "); + asm("strb r1, [r0, #5] "); + asm("strb r1, [r3, #%a0]" : : "i" ((TInt)K16550LCROffset)); + asm("msr cpsr, ip "); + __JUMP(,lr); + } + +__NAKED__ void T16550Uart::SetMCR(TUint /*aValue*/) + { + asm("mrs ip, cpsr "); + asm("ldr r3, [r0, #0] "); + asm("orr r2, ip, #0xc0 "); + asm("msr cpsr, r2 "); + asm("strb r1, [r0, #6] "); + asm("strb r1, [r3, #%a0]" : : "i" ((TInt)K16550MCROffset)); + asm("msr cpsr, ip "); + __JUMP(,lr); + } + +__NAKED__ void T16550Uart::SetIER(TUint /*aValue*/) + { + asm("mrs ip, cpsr "); + asm("ldr r3, [r0, #0] "); + asm("orr r2, ip, #0xc0 "); + asm("msr cpsr, r2 "); + asm("strb r1, [r0, #7] "); + asm("strb r1, [r3, #%a0]" : : "i" ((TInt)K16550IEROffset)); + asm("msr cpsr, ip "); + __JUMP(,lr); + } diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/uart/uart16550_ne.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/uart/uart16550_ne.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,776 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\uart\uart16550.cpp +* PDD for 16550 UART +* +*/ + + + +#include +#include +#include "../naviengine_priv.h" +#include "../naviengine.h" +#include "uart16550_ne.h" +#include + +_LIT(KPddName,"Comm.16550_ne"); + +#define __COMMS_MACHINE_CODED__ +#ifdef __COMMS_MACHINE_CODED__ +#define DBASE_VPTR_OFFSET 4 +#define RX_ISR_VT_OFFSET 0x24 +#define CHK_TXB_VT_OFFSET 0x28 +#define STATE_ISR_VT_OFFSET 0x2C +#endif + +// needs ldd version.. +const TInt KMinimumLddMajorVersion=1; +const TInt KMinimumLddMinorVersion=1; +const TInt KMinimumLddBuild=122; + +// The following defines when enabled can help debugging uart: + +// RX_WORKAROUND - The basic workaround. There is a small window where data loss could occur +// #define RX_WORKAROUND + +// RX_WORKAROUND_SAVE - A more advanced workaround that notifies the LDD that there +// has been a read error. May cause new reporting of errors +// #define RX_WORKAROUND_SAVE + +// TRACK_WORKAROUND - Records the number activations of the workaround +// and the state of the last one. printf's the values on on deconstruct +// #define TRACK_WORKAROUND + +// TRACK_DISTRIBUTION - Records the number of bytes read at a time to +// demonstrate operation of fifo mode. printf's the values on on deconstruct +// #define TRACK_DISTRIBUTION + +// DISABLE_RX_FLUSH - Disables RX Flush in uart configuration procedure. +// #define DISABLE_RX_FLUSH + +// TEMPORARY_SMP_FIX reduces the number of bytes pumped into the Tx FIFO from 16 to 8 +// which works around a hardware problem not fully understood. +#define TEMPORARY_SMP_FIX + +// configuration data +static const TUint16 BaudRateDivisor[] = + { + KBaudRateDiv_50, + KBaudRateDiv_75, + KBaudRateDiv_110, + KBaudRateDiv_134, + KBaudRateDiv_150, + KBaudRateDiv_300, + KBaudRateDiv_600, + KBaudRateDiv_1200, + KBaudRateDiv_1800, + KBaudRateDiv_2000, + KBaudRateDiv_2400, + KBaudRateDiv_3600, + KBaudRateDiv_4800, + KBaudRateDiv_7200, + KBaudRateDiv_9600, + KBaudRateDiv_19200, + KBaudRateDiv_38400, + KBaudRateDiv_57600, + KBaudRateDiv_115200, + KBaudRateDiv_230400, + }; + +class DDriverComm : public DPhysicalDevice + { +public: + DDriverComm(); + ~DDriverComm(); + virtual TInt Install(); + virtual void GetCaps(TDes8 &aDes) const; + virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion &aVer); + virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer); +public: + TDynamicDfcQue* iDfcQ; + }; + +class DComm16550 : public DComm + { +public: + DComm16550(); + ~DComm16550(); + TInt DoCreate(TInt aUnit, const TDesC8* anInfo, TDynamicDfcQue* aDfcQ); +public: + virtual TInt Start(); + virtual void Stop(TStopMode aMode); + virtual void Break(TBool aState); + virtual void EnableTransmit(); + virtual TUint Signals() const; + virtual void SetSignals(TUint aSetMask,TUint aClearMask); + virtual TInt ValidateConfig(const TCommConfigV01 &aConfig) const; + virtual void Configure(TCommConfigV01 &aConfig); + virtual void Caps(TDes8 &aCaps) const; + virtual TInt DisableIrqs(); + virtual void RestoreIrqs(TInt aIrq); + virtual TDfcQue* DfcQ(TInt aUnit); + virtual void CheckConfig(TCommConfigV01& aConfig); +public: + static void Isr(TAny* aPtr); +public: + TInt iInterruptId; + TInt iUnit; + T16550Uart* iUart; + TDynamicDfcQue* iDfcQ; + +#ifdef TRACK_WORKAROUND + TInt iWorkaround; // how many times did the workaround fire + TInt iWorkaroundLSR; + TInt iWorkaroundISR; +#endif + +#ifdef TRACK_DISTRIBUTION + TUint iRead[33]; // array of how many bytes reported back to the ldd +#endif + }; + + +DDriverComm::DDriverComm() +// +// Constructor +// + { + iUnitsMask=~(0xffffffffu<iThread), KCpuAffinityAny); +#endif + r = SetName(&KPddName); + } + return r; + } + +/** + Destructor +*/ +DDriverComm::~DDriverComm() + { + if (iDfcQ) + iDfcQ->Destroy(); + } + +void Get16550CommsCaps(TDes8& aCaps, TInt aUnit) + { + TCommCaps3 capsBuf; + TCommCapsV03 &c=capsBuf(); + c.iRate = + KCapsBps150 + |KCapsBps300 + |KCapsBps600 + |KCapsBps1200 + |KCapsBps1800 + |KCapsBps2000 + |KCapsBps2400 + |KCapsBps3600 + |KCapsBps4800 + |KCapsBps7200 + |KCapsBps9600 + |KCapsBps19200 + |KCapsBps38400 + |KCapsBps57600 + |KCapsBps115200; + if (aUnit != 2) + { + c.iRate |= KCapsBps230400; + } + + c.iDataBits = + KCapsData5 + |KCapsData6 + |KCapsData7 + |KCapsData8; + c.iStopBits = + KCapsStop1 + |KCapsStop2; + c.iParity = + KCapsParityNone + |KCapsParityEven + |KCapsParityOdd + |KCapsParityMark + |KCapsParitySpace; + c.iSIR = 0; + switch (aUnit) + { + case 0: + c.iHandshake = + KCapsObeyXoffSupported + |KCapsSendXoffSupported + |KCapsObeyCTSSupported + |KCapsFailCTSSupported + |KCapsFreeRTSSupported; + c.iSignals = + KCapsSignalCTSSupported + |KCapsSignalRTSSupported; + break; + case 1: + c.iHandshake = + KCapsObeyXoffSupported + |KCapsSendXoffSupported + |KCapsObeyCTSSupported + |KCapsFailCTSSupported + |KCapsObeyDSRSupported + |KCapsFailDSRSupported + |KCapsObeyDCDSupported + |KCapsFailDCDSupported + |KCapsFreeRTSSupported + |KCapsFreeDTRSupported; + c.iSignals = + KCapsSignalCTSSupported + |KCapsSignalRTSSupported + |KCapsSignalDTRSupported + |KCapsSignalDSRSupported + |KCapsSignalDCDSupported; + break; + default: + case 2: + c.iHandshake = + KCapsObeyXoffSupported + |KCapsSendXoffSupported; + c.iSignals = 0; + break; + } + c.iFifo=KCapsHasFifo; + c.iNotificationCaps= + KNotifyDataAvailableSupported + |KNotifySignalsChangeSupported; + c.iRoleCaps = 0; + c.iFlowControlCaps = 0; + c.iBreakSupported = ETrue; + aCaps.FillZ(aCaps.MaxLength()); + aCaps=capsBuf.Left(Min(capsBuf.Length(),aCaps.MaxLength())); + } + +void DDriverComm::GetCaps(TDes8 &aDes) const +// +// Return the drivers capabilities +// + { + Get16550CommsCaps(aDes, 0); + } + +TInt DDriverComm::Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer) +// +// Create a driver +// + { + DComm16550* pD=new DComm16550; + aChannel=pD; + TInt r=KErrNoMemory; + if (pD) + r=pD->DoCreate(aUnit,anInfo, iDfcQ); + return r; + } + +TInt DDriverComm::Validate(TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& aVer) +// +// Validate the requested configuration +// + { + if ((!Kern::QueryVersionSupported(iVersion,aVer)) || (!Kern::QueryVersionSupported(aVer,TVersion(KMinimumLddMajorVersion,KMinimumLddMinorVersion,KMinimumLddBuild)))) + return KErrNotSupported; + if (TUint(aUnit)>=TUint(KNum16550Uarts)) + return KErrNotSupported; + return KErrNone; + } + +DComm16550::DComm16550() +// +// Constructor +// + { +// iTransmitting=EFalse; + iInterruptId=-1; // -1 means not bound + } + +DComm16550::~DComm16550() +// +// Destructor +// + { + if (iUart) + delete iUart; + if (iInterruptId>=0) + Interrupt::Unbind(iInterruptId); + +#ifdef TRACK_WORKAROUND + if (iWorkaround) + { + Kern::Printf("########################################"); + Kern::Printf("####%d iWorkaround %d LSR 0x%x ISR 0x%x", iUnit, iWorkaround, iWorkaroundLSR, iWorkaroundISR); + Kern::Printf("########################################"); + } + else + { + Kern::Printf("####%d iWorkaround %d LSR 0x%x ISR 0x%x", iUnit, iWorkaround, iWorkaroundLSR, iWorkaroundISR); + } +#endif +#ifdef TRACK_DISTRIBUTION + Kern::Printf("####%d iRead: %d, %d %d %d %d %d %d %d %d, %d %d %d %d %d %d %d %d, %d %d %d %d %d %d %d %d, %d %d %d %d %d %d %d", + iUnit, + iRead[0], + iRead[1], iRead[2], iRead[3], iRead[4], iRead[5], iRead[6], iRead[7], iRead[8], + iRead[9], iRead[10], iRead[11], iRead[12], iRead[13], iRead[14], iRead[15], iRead[16], + iRead[17], iRead[18], iRead[19], iRead[20], iRead[21], iRead[22], iRead[23], iRead[24], + iRead[25], iRead[26], iRead[27], iRead[28], iRead[29], iRead[30], iRead[31], iRead[32]); +#endif + } + +TInt DComm16550::DoCreate(TInt aUnit, const TDesC8* /*anInfo*/, TDynamicDfcQue* aDfcQ) +// +// Sets up the PDD +// + { + TUint base; + + switch (aUnit) + { + case 0: + base=KHwBaseUart0; + break; + case 1: + base=KHwBaseUart1; + break; + case 2: + base=KHwBaseUart2; + break; + default: + return KErrNotSupported; + } + + iUnit=aUnit; + iDfcQ = aDfcQ; + TInt irq=KIntIdUart0+aUnit; + + // bind to UART interrupt + TInt r=Interrupt::Bind(irq,Isr,this); + if (r>=0) + { + iInterruptId = r; + r = KErrNone; + + iUart = new T16550Uart; + if (iUart) + { + iUart->iBase = (TUint8*)base; + iUart->SetIER(0); + iUart->SetLCR(0); + iUart->SetFCR(0); + iUart->SetMCR(0); + } + else + { + Interrupt::Unbind(iInterruptId); + r = KErrNoMemory; + } + } + +#ifdef TRACK_WORKAROUND + iWorkaround = iWorkaroundLSR = iWorkaroundISR = 0; +#endif + return r; + } + +TDfcQue* DComm16550::DfcQ(TInt /*aUnit*/) +// +// Return the DFC queue to be used for this device +// For PC cards, use the PC card controller thread for the socket in question. +// + { + return iDfcQ; + } + +TInt DComm16550::Start() +// +// Start receiving characters +// + { + // if EnableTransmit() called before Start() + iTransmitting=EFalse; + iUart->SetIER(K16550IER_RDAI|K16550IER_RLSI|K16550IER_MSI); + iLdd->UpdateSignals(Signals()); + Interrupt::Enable(iInterruptId); + return KErrNone; + } + +TBool FinishedTransmitting(TAny* aPtr) + { + DComm16550& d=*(DComm16550*)aPtr; + return d.iUart->TestLSR(K16550LSR_TxIdle); + } + +void DComm16550::Stop(TStopMode aMode) +// +// Stop receiving characters +// + { + switch (aMode) + { + case EStopNormal: + case EStopPwrDown: + iUart->SetIER(0); + Interrupt::Disable(iInterruptId); + iTransmitting=EFalse; + + // wait for uart to stop tranmitting + Kern::PollingWait(FinishedTransmitting,this,3,100); + break; + case EStopEmergency: + iUart->SetIER(0); + Interrupt::Disable(iInterruptId); + iTransmitting=EFalse; + break; + } + } + +void DComm16550::Break(TBool aState) +// +// Start or stop the uart breaking +// + { + if (aState) + iUart->ModifyLCR(0,K16550LCR_TxBreak); + else + iUart->ModifyLCR(K16550LCR_TxBreak,0); + } + +void DComm16550::EnableTransmit() +// +// Start sending characters. +// + { + TBool tx = (TBool)__e32_atomic_swp_ord32(&iTransmitting, 1); + if (tx) + return; + iUart->ModifyIER(0,K16550IER_THREI); + } + +TUint DComm16550::Signals() const +// +// Read and translate the modem lines +// + { + TUint msr=iUart->MSR(); + msr=((msr>>4)&0x0f); // true input signals + TUint sig=msr & 3; // CTS,DSR OK + if (msr & 4) + sig|=KSignalRNG; // swap DCD,RNG + if (msr & 8) + sig|=KSignalDCD; + + return sig; + } + +void DComm16550::SetSignals(TUint aSetMask, TUint aClearMask) +// +// Set signals. +// + { + TUint set=0; + TUint clear=0; + if (aSetMask & KSignalRTS) + set|=K16550MCR_RTS; + if (aSetMask & KSignalDTR) + set|=K16550MCR_DTR; + if (aClearMask & KSignalRTS) + clear|=K16550MCR_RTS; + if (aClearMask & KSignalDTR) + clear|=K16550MCR_DTR; + iUart->ModifyMCR(clear,set); + } + +TInt DComm16550::ValidateConfig(const TCommConfigV01 &aConfig) const +// +// Check a config structure. +// + { + if (aConfig.iSIREnable==ESIREnable) + return KErrNotSupported; + switch (aConfig.iParity) + { + case EParityNone: + case EParityOdd: + case EParityEven: + case EParityMark: + case EParitySpace: + break; + default: + return KErrNotSupported; + } +// if (TUint(aConfig.iRate)>TUint(EBps115200)) +// return KErrNotSupported; + return KErrNone; + } + +void DComm16550::CheckConfig(TCommConfigV01& aConfig) + { + // do nothing + } + +TInt DComm16550::DisableIrqs() +// +// Disable normal interrupts +// + { + + return NKern::DisableInterrupts(1); + } + +void DComm16550::RestoreIrqs(TInt aLevel) +// +// Restore normal interrupts +// + { + + NKern::RestoreInterrupts(aLevel); + } + +void DComm16550::Configure(TCommConfigV01 &aConfig) +// +// Set up the Uart +// + { + // wait for uart to stop tranmitting + Kern::PollingWait(FinishedTransmitting,this,3,100); + + TUint lcr=0; + switch (aConfig.iDataBits) + { + case EData5: + lcr=K16550LCR_Data5; + break; + case EData6: + lcr=K16550LCR_Data6; + break; + case EData7: + lcr=K16550LCR_Data7; + break; + case EData8: + lcr=K16550LCR_Data8; + break; + } + switch (aConfig.iStopBits) + { + case EStop1: + break; + case EStop2: + lcr|=K16550LCR_Stop2; + break; + } + switch (aConfig.iParity) + { + case EParityNone: + break; + case EParityEven: + lcr|=K16550LCR_ParityEnable|K16550LCR_ParityEven; + break; + case EParityOdd: + lcr|=K16550LCR_ParityEnable; + break; + case EParityMark: + lcr|=K16550LCR_ParityEnable|K16550LCR_ParityMark; + break; + case EParitySpace: + lcr|=K16550LCR_ParityEnable|K16550LCR_ParitySpace; + break; + } + + /* + S18599EJ1V5UM.pdf page 746 uart configuration + Caution: Must not change the baud rate while any data transfers are executing. + If the baud rate is necessary to changed, please apply following sequence. + ... (inlined with code) ... + */ + + // 1) Put UART in Local loop-back mode (write 1 to MCR4 bit). + iUart->ModifyMCR(0,K16550MCR_LocalLoop); + + // 2) Clear transmit FIFO (write 1 to FCR2 bit). + iUart->SetFCR(K16550FCR_TxReset); + + // 3) Wait 1 character period (ex. 100µs at 115kbps) + NKern::Sleep(1); // sleep 1ms (for, 9600 bump up to 2ms?) + + // 4) Clear receive buffer (read RBR register until LSR0 bit becomes 0). + TInt maxdrain = 1000; // arbitrary count (fifo depth is 16 bytes) + while (iUart->TestLSR(K16550LSR_RxReady) && --maxdrain) + iUart->RxData(); // read character from RBR + + // 5) Clear receive FIFO (write 1 to FCR1 bit). + iUart->SetFCR(K16550FCR_RxReset); + + // 6) Change the baud rate (write 1 to LCR7, write DLL and DLH, and then write 0 to LCR7). + iUart->SetLCR(lcr|K16550LCR_DLAB); + iUart->SetBaudRateDivisor(BaudRateDivisor[(TInt)aConfig.iRate]); + iUart->SetLCR(lcr); + + // 7) Go back to normal mode (write 0 to MCR4 bit). + iUart->ModifyMCR(K16550MCR_LocalLoop, 0); + + // Enable fifo mode + //iUart->SetFCR(K16550FCR_Enable | K16550FCR_TxRxRdy | K16550FCR_RxTrig8); + iUart->SetFCR(K16550FCR_Enable | K16550FCR_RxTrig8); + +#ifndef DISABLE_RX_FLUSH + // Read characters from RBR; this isn't part of the recommended baud rate change code + // but this has fixed the problem with ISR running indefinitely. + TInt j; + for (j=0;j<16;j++) // Fifo buffer is 16 bytes deep + iUart->RxData(); +#endif + +#ifdef TRACK_DISTRIBUTION + // blank an array of 33 integers 0 to 32 + TInt i=0; + for (i=0;i<33;i++) + { + iRead[i]=0; + } +#endif + } + +void DComm16550::Caps(TDes8 &aCaps) const +// +// return our caps +// + { + Get16550CommsCaps(aCaps,iUnit); + } + +void DComm16550::Isr(TAny* aPtr) +// +// Service the UART interrupt +// + { + DComm16550& d=*(DComm16550*)aPtr; + T16550Uart& u=*d.iUart; + TUint rx[32]; + TUint xon=d.iLdd->iRxXonChar; + TUint xoff=d.iLdd->iRxXoffChar; + + TUint isr=u.ISR(); + if (isr & K16550ISR_NotPending) + return; + isr&=K16550ISR_IntIdMask; + + // if receive data available or line status interrupt + if (isr==K16550ISR_RDAI || isr==K16550ISR_RLSI) + { + TInt rxi=0; + TInt x=0; + +#if defined(RX_WORKAROUND) || defined(RX_WORKAROUND_SAVE) + // It has been observed that the hardware can assert RDAI without asserting RxReady + // This is nasty but it reads from the head of the fifo, ORs in a faked error + // and saves it in the buffer, later on in the loop it will be passed to the ldd + // as data with an error + if (!(u.LSR() & K16550LSR_RxReady)) + { +#ifdef TRACK_WORKAROUND + ++d.iWorkaround; + d.iWorkaroundLSR=u.LSR(); + d.iWorkaroundISR=u.ISR(); +#endif + +#ifdef RX_WORKAROUND_SAVE + // save the character and flag error, this is a bit risky as it could report errors + rx[rxi++]=(u.RxData() | KReceiveIsrFrameError); +#else // or just discard it (normal workaround) + u.RxData(); +#endif + } +#endif + while (u.TestLSR(K16550LSR_RxReady|K16550LSR_RxParityErr|K16550LSR_RxOverrun|K16550LSR_RxFrameErr|K16550LSR_RxBreak) && Kern::PowerGood()) + { + TUint lsr=0; + // checks for EIF flag + if (isr==K16550ISR_RLSI) + lsr=u.LSR()&(K16550LSR_RxParityErr|K16550LSR_RxOverrun|K16550LSR_RxFrameErr); + TUint ch=u.RxData(); + // if error in this character + if (lsr) + { + if (lsr & K16550LSR_RxParityErr) + ch|=KReceiveIsrParityError; + if (lsr & K16550LSR_RxBreak) + ch|=KReceiveIsrBreakError; + if (lsr & K16550LSR_RxFrameErr) + ch|=KReceiveIsrFrameError; + if (lsr & K16550LSR_RxOverrun) + ch|=KReceiveIsrOverrunError; + } + if (ch==xon) + x=1; + else if (ch==xoff) + x=-1; + else + rx[rxi++]=ch; + } +#ifdef TRACK_DISTRIBUTION + d.iRead[rxi]++; // record how many bytes we're reporting +#endif + d.ReceiveIsr(rx,rxi,x); + return; + } + // if TFS flag and TIE + if (isr==K16550ISR_THREI) + { + TInt n; +#ifdef TEMPORARY_SMP_FIX + for (n=0; n<8; ++n) +#else + for (n=0; n<16; ++n) +#endif + { + TInt r=d.TransmitIsr(); + if (r<0) + { + //no more to send + // Disable the TX interrupt + u.ModifyIER(K16550IER_THREI,0); + d.iTransmitting=EFalse; + break; + } + u.SetTxData(r); + } + d.CheckTxBuffer(); + return; + } + // must be signal change + d.StateIsr(d.Signals()); + } + +DECLARE_STANDARD_PDD() + { + return new DDriverComm; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/uart/uart16550_ne.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/uart/uart16550_ne.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,180 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\uart\uart16550.h +* +*/ + + + +/** + @file + @internalTechnology +*/ + +#ifndef __UART16550_H__ +#define __UART16550_H__ +#include + +// +// reg_def.h +// +const TUint K16550OffsetShift = 2; +const TUint KNum16550Uarts = 3; +const TInt KUart16550ThreadPriority = 27; +_LIT(KUar16550tDriverThread,"UART16550_Thread"); + + +// +// Register Definitions for 16550-type UARTs +// + +const TUint8 K16550TXHROffset=0<=1 char received +const TUint8 K16550FCR_RxTrig4=64; // RX FIFO triggers when >=4 chars received +const TUint8 K16550FCR_RxTrig8=128; // RX FIFO triggers when >=8 chars received +const TUint8 K16550FCR_RxTrig14=192; // RX FIFO triggers when >=14 chars received + +// Line Control Register + +const TUint8 K16550LCR_Data5=0; // 5 bit characters +const TUint8 K16550LCR_Data6=1; // 6 bit characters +const TUint8 K16550LCR_Data7=2; // 7 bit characters +const TUint8 K16550LCR_Data8=3; // 8 bit characters +const TUint8 K16550LCR_Stop1=0; // 1 stop bit +const TUint8 K16550LCR_Stop2=4; // 2 stop bits +const TUint8 K16550LCR_ParityEnable=8; // Use parity +const TUint8 K16550LCR_ParityEven=16; // Use even parity +const TUint8 K16550LCR_ParityMark=40; // Use mark parity +const TUint8 K16550LCR_ParitySpace=56; // Use space parity +const TUint8 K16550LCR_TxBreak=64; // Transmit a break +const TUint8 K16550LCR_DLAB=128; // Divisor Latch Access + +// Modem Control Register + +const TUint8 K16550MCR_DTR=1; +const TUint8 K16550MCR_RTS=2; +const TUint8 K16550MCR_OUT1=4; +const TUint8 K16550MCR_OUT2=8; +const TUint8 K16550MCR_LocalLoop=16; + +// Line Status Register + +const TUint8 K16550LSR_RxReady=1; // Received data ready +const TUint8 K16550LSR_RxOverrun=2; // Receiver overrun +const TUint8 K16550LSR_RxParityErr=4; // Receiver parity error +const TUint8 K16550LSR_RxFrameErr=8; // Receiver framing error +const TUint8 K16550LSR_RxBreak=16; // Receive break detect +const TUint8 K16550LSR_TXHREmpty=32; // Transmit Holding Register Empty (FIFO empty) +const TUint8 K16550LSR_TxIdle=64; // Transmitter Idle +const TUint8 K16550LSR_RxErrPending=128; // FIFO contains an error or break indication + +// Modem Status Register + +const TUint8 K16550MSR_DeltaCTS=1; +const TUint8 K16550MSR_DeltaDSR=2; +const TUint8 K16550MSR_TERI=4; +const TUint8 K16550MSR_DeltaDCD=8; +const TUint8 K16550MSR_CTS=16; +const TUint8 K16550MSR_DSR=32; +const TUint8 K16550MSR_RI=64; +const TUint8 K16550MSR_DCD=128; + +// Wrapper class + +class T16550Uart + { +public: + void ModifyFCR(TUint aClearMask, TUint aSetMask); + void ModifyLCR(TUint aClearMask, TUint aSetMask); + void ModifyMCR(TUint aClearMask, TUint aSetMask); + void ModifyIER(TUint aClearMask, TUint aSetMask); + void SetFCR(TUint aValue); + void SetLCR(TUint aValue); + void SetMCR(TUint aValue); + void SetIER(TUint aValue); + inline TUint FCR() + {return iFCR;} + inline TUint LCR() + {return iLCR;} + inline TUint MCR() + {return iMCR;} + inline TUint IER() + {return iIER;} + inline void SetTxData(TUint aData) + {iBase[K16550TXHROffset]=(TUint8)aData;} + inline TUint RxData() + {return iBase[K16550RXHROffset];} + inline TUint ISR() + {return iBase[K16550ISROffset];} + inline TUint LSR() + {return iBase[K16550LSROffset];} + inline TUint MSR() + {return iBase[K16550MSROffset];} + inline TUint TestISR(TUint aMask) + {return iBase[K16550ISROffset]&aMask;} + inline TUint TestLSR(TUint aMask) + {return iBase[K16550LSROffset]&aMask;} + inline TUint TestMSR(TUint aMask) + {return iBase[K16550MSROffset]&aMask;} + inline void SetScratch(TUint aValue) + {iBase[K16550ScratchpadOffset]=(TUint8)aValue;} + inline TUint Scratch() + {return iBase[K16550ScratchpadOffset];} + inline void SetBaudRateDivisor(TUint aValue) + {iBase[K16550BDHiOffset]=(TUint8)(aValue>>8); iBase[K16550BDLoOffset]=(TUint8)aValue;} +public: + volatile TUint8* iBase; // base address + TUint8 iFCR; // FCR follower + TUint8 iLCR; // LCR follower + TUint8 iMCR; // MCR follower + TUint8 iIER; // IER follower + }; + +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/uart/ubootldrkeyb.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/uart/ubootldrkeyb.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp/uart/ubootldrkeyb.mmp +* The extension enables keyboard input via the debugport UART connection +* +*/ + + +/** + @file +*/ + +#include +#include "kernel/kern_ext.mmh" + +USERINCLUDE ../ +USERINCLUDE ../../../navienginebootldr/inc +USERINCLUDE ../../../../../os/kernelhwsrv/brdbootldr/ubootldr/inc +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +library VariantTarget(kanaviengine,lib) VariantTarget(ecust,lib) + +target VariantTarget(ubootldrkeyb,dll) +targettype kext + +sourcepath . +source vserialkeyb.cpp uart16550_ne.cia ubootldrkeybport.cpp + + +deffile ../../../../../os/kernelhwsrv/kernel/eka/~/empty.def + +uid 0x1000008d 0x100039e8 +romtarget ekeyb.dll +capability all +VENDORID 0x70000001 + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/uart/ubootldrkeybport.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/uart/ubootldrkeybport.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,111 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\uart\vserialkeyb.cpp +* Serial keyboard driver +* +*/ + + +/** + @file + @internalTechnology +*/ + +#include +#include +#include +#include "../naviengine.h" +#include +#include "uart16550_ne.h" +#include "vserialkeyb.h" +#include "bootloader_variantconfig.h" + +TInt TSerialKeyboard::GetSerialPort(TUint& aBaud) + { + // Get the Ymodem serial port from NOR Flash config values and set the keyboard port appropriately. + // + // The debug port should be the same as the Ymodem port. The keyboard port should never be the same + // as the Ymodem port or else the image will fail to boot. + // + // Don't use port 2 as the keyboard port because we may not have a port 2 on the board. + // + // Therefore, depending on the YmodemG download port, set the keyboard port as follows: + // + // Ymodem Keyboard + // 0 1 + // 1 0 + // 2 1 + + TInt keyboardPort = 1; + aBaud = 115200; + TUint32 ConfigBlockAddressPhys = KNORFlashMaxBootloaderSize - KFlashEraseBlockSize; + + __KTRACE_OPT(KEXTENSION,Kern::Printf("ubootldrkeyb: KNORFlashTargetAddr = %x", KNORFlashTargetAddr )); + __KTRACE_OPT(KEXTENSION,Kern::Printf("ubootldrkeyb: KNORFlashTargetSize = %x", KNORFlashTargetSize )); + __KTRACE_OPT(KEXTENSION,Kern::Printf("ubootldrkeyb: KNORFlashMaxBootloaderSize = %x", KNORFlashMaxBootloaderSize)); + __KTRACE_OPT(KEXTENSION,Kern::Printf("ubootldrkeyb: KNORFlashMaxImageSize = %x", KNORFlashMaxImageSize )); + __KTRACE_OPT(KEXTENSION,Kern::Printf("ubootldrkeyb: KFlashEraseBlockSize = %x", KFlashEraseBlockSize )); + __KTRACE_OPT(KEXTENSION,Kern::Printf("ubootldrkeyb: ConfigBlockAddressPhys = %x", ConfigBlockAddressPhys )); + + { + DPlatChunkHw * chunk; + + TInt errorCode = DPlatChunkHw::New(chunk, ConfigBlockAddressPhys, KFlashEraseBlockSize, EMapAttrSupRw | EMapAttrFullyBlocking); + + if (errorCode == KErrNone) + { + TUint32 linearAddr = (TUint)chunk->LinearAddress(); + + __KTRACE_OPT(KEXTENSION,Kern::Printf("ubootldrkeyb: linearAddr = %x", linearAddr)); + + SBootloaderConfig * configBlockPtr = (SBootloaderConfig * )linearAddr; + + //TUint32 magic = *((TUint32*)linearAddr); + if (configBlockPtr->iMagic == KUidUBootldrCfgMagic) + { + // valid config block + __KTRACE_OPT(KEXTENSION,Kern::Printf("ubootldrkeyb: Valid config block, magic=%x", configBlockPtr->iMagic)); + __KTRACE_OPT(KEXTENSION,Kern::Printf("ubootldrkeyb: ymodemPort == %d from NOR flash", configBlockPtr->iPortNumber)); + + switch (configBlockPtr->iPortNumber) + { + default: + case 0: keyboardPort=1; break; + case 1: keyboardPort=0; break; + case 2: keyboardPort=1; break; + } + + // Set the debug port to be the same as the Ymodem download port so that error messages get logged by trgtest + Kern::SuperPage().iDebugPort = configBlockPtr->iPortNumber; + } + else + { + // invalid config block + __KTRACE_OPT(KEXTENSION,Kern::Printf("ubootldrkeyb: Invlaid config block, magic=%x", configBlockPtr->iMagic)); + } + } + else + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("ubootldrkeyb: error: failed to allocate chunk (%d)", errorCode)); + } + + // close the chunk + chunk->Close(chunk); + } + + __KTRACE_OPT(KEXTENSION,Kern::Printf("ubootldrkeyb: keyboardPort == %d", keyboardPort)); + return keyboardPort; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/uart/vserialkeyb.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/uart/vserialkeyb.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,470 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\uart\vserialkeyb.cpp +* Serial keyboard driver +* +*/ + + + +/** + @file + @internalTechnology +*/ + +#include +#include +#include +#include "../naviengine_priv.h" +#include "../naviengine.h" +#include "uart16550_ne.h" +#include "vserialkeyb.h" + + +#define SHIFTED(x) (0x8000|(x)) +#define ISSHIFTED(x) (0x8000&(x)) +#define FUNCED(x) (0x4000|(x)) +#define ISFUNCED(x) (0x4000&(x)) +#define CTRLED(x) (0x2000|(x)) +#define ISCTRLED(x) (0x2000&(x)) +#define STDKEY(x) (0x1FFF&(x)) + +/* + * Definition of the converting table for the receive char + * through the serial port. + * + */ +const TUint16 convertCodeSerial[] = +{ +/*00*/ EStdKeyNull, +/*01*/ EStdKeyHome, // ^A +/*02*/ EStdKeyLeftArrow, // ^B +/*03*/ EStdKeyEscape, // ^C +/*04*/ SHIFTED(EStdKeyDownArrow), // ^D - move window down +/*05*/ EStdKeyEnd, // ^E +/*06*/ EStdKeyRightArrow, // ^F +/*07*/ EStdKeyNull, +/*08*/ EStdKeyBackspace, // ^H - Reserved! +/*09*/ EStdKeyTab, // ^I - Reserved! +/*0a*/ EStdKeyNull, +/*0b*/ EStdKeyIncContrast, // ^K +/*0c*/ EStdKeyDecContrast, // ^L +/*0d*/ EStdKeyEnter, // ^M - Reserved! +/*0e*/ EStdKeyDownArrow, // ^N +/*0f*/ EStdKeyNull, // ^O = instant death +/*10*/ EStdKeyUpArrow, // ^P +/*11*/ CTRLED(EStdKeyLeftArrow), // ^Q - make window narrower +/*12*/ CTRLED(FUNCED('5')), // ^R - rotate windows in text window server +/*13*/ EStdKeyNull, +/*14*/ CTRLED(EStdKeyDownArrow), // ^T - make window taller +/*15*/ SHIFTED(EStdKeyUpArrow), // ^U - move window up +/*16*/ EStdKeyNull, +/*17*/ CTRLED(EStdKeyRightArrow), // ^W - make window wider +/*18*/ SHIFTED(EStdKeyRightArrow), // ^X - move window right +/*19*/ CTRLED(EStdKeyUpArrow), // ^Y - make window shorter +/*1a*/ SHIFTED(EStdKeyLeftArrow), // ^Z - move window left +/*1b*/ EStdKeyEscape, // ^[ - Reserved! +/*1c*/ EStdKeyNull, +/*1d*/ EStdKeyNull, +/*1e*/ EStdKeyNull, +/*1f*/ EStdKeyNull, +/*20*/ EStdKeySpace, +/*21*/ SHIFTED('1'), // ! +/*22*/ SHIFTED('2'), // " +/*23*/ EStdKeyHash, // # +/*24*/ SHIFTED('4'), // $ +/*25*/ SHIFTED('5'), // % +/*26*/ SHIFTED('7'), // & +/*27*/ EStdKeySingleQuote, +/*28*/ SHIFTED('9'), // ( +/*29*/ SHIFTED('0'), // ) +/*2a*/ SHIFTED('8'), // * +/*2b*/ SHIFTED(EStdKeyEquals), // + +/*2c*/ EStdKeyComma, +/*2d*/ EStdKeyMinus, +/*2e*/ EStdKeyFullStop, +/*2f*/ EStdKeyForwardSlash, +/*30*/ '0', +/*31*/ '1', +/*32*/ '2', +/*33*/ '3', +/*34*/ '4', +/*35*/ '5', +/*36*/ '6', +/*37*/ '7', +/*38*/ '8', +/*39*/ '9', +/*3a*/ SHIFTED(EStdKeySemiColon), // : +/*3b*/ EStdKeySemiColon, +/*3c*/ SHIFTED(EStdKeyComma), // < +/*3d*/ EStdKeyEquals, +/*3e*/ SHIFTED(EStdKeyFullStop), // > +/*3f*/ SHIFTED(EStdKeyForwardSlash), // ? +/*40*/ SHIFTED(EStdKeySingleQuote), // @ +/*41*/ SHIFTED('A'), +/*42*/ SHIFTED('B'), +/*43*/ SHIFTED('C'), +/*44*/ SHIFTED('D'), +/*45*/ SHIFTED('E'), +/*46*/ SHIFTED('F'), +/*47*/ SHIFTED('G'), +/*48*/ SHIFTED('H'), +/*49*/ SHIFTED('I'), +/*4a*/ SHIFTED('J'), +/*4b*/ SHIFTED('K'), +/*4c*/ SHIFTED('L'), +/*4d*/ SHIFTED('M'), +/*4e*/ SHIFTED('N'), +/*4f*/ SHIFTED('O'), +/*50*/ SHIFTED('P'), +/*51*/ SHIFTED('Q'), +/*52*/ SHIFTED('R'), +/*53*/ SHIFTED('S'), +/*54*/ SHIFTED('T'), +/*55*/ SHIFTED('U'), +/*56*/ SHIFTED('V'), +/*57*/ SHIFTED('W'), +/*58*/ SHIFTED('X'), +/*59*/ SHIFTED('Y'), +/*5a*/ SHIFTED('Z'), +/*5b*/ EStdKeySquareBracketLeft, +/*5c*/ EStdKeyBackSlash, +/*5d*/ EStdKeySquareBracketRight, +/*5e*/ SHIFTED('6'), // ^ +/*5f*/ SHIFTED(EStdKeyMinus), // _ +/*60*/ EStdKeyBacklightToggle, // Actually ` +/*61*/ 'A', +/*62*/ 'B', +/*63*/ 'C', +/*64*/ 'D', +/*65*/ 'E', +/*66*/ 'F', +/*67*/ 'G', +/*68*/ 'H', +/*69*/ 'I', +/*6a*/ 'J', +/*6b*/ 'K', +/*6c*/ 'L', +/*6d*/ 'M', +/*6e*/ 'N', +/*6f*/ 'O', +/*70*/ 'P', +/*71*/ 'Q', +/*72*/ 'R', +/*73*/ 'S', +/*74*/ 'T', +/*75*/ 'U', +/*76*/ 'V', +/*77*/ 'W', +/*78*/ 'X', +/*79*/ 'Y', +/*7a*/ 'Z', +/*7b*/ SHIFTED(EStdKeySquareBracketLeft), +/*7c*/ SHIFTED(EStdKeyBackSlash), +/*7d*/ SHIFTED(EStdKeySquareBracketRight), +/*7e*/ SHIFTED(EStdKeyHash), +/*7f*/ EKeyDelete +}; /* end of array - convertCodeSerial - */ + +typedef struct + { + TUint8 seq[maxSeq+1]; + TUint32 convertedCode; + } keyType; + +const keyType escapeCodes[] = +{ + // Three escape codes in a row that completes a sequence + { {0x1b, 0x4f, 0x50, 0, 0, 0,}, EStdKeyMenu, }, // F1 gives menu key + { {0x1b, 0x4f, 0x51, 0, 0, 0,}, EStdKeyF2, }, // F2 + { {0x1b, 0x4f, 0x52, 0, 0, 0,}, EStdKeyF3, }, // F3 + { {0x1b, 0x4f, 0x53, 0, 0, 0,}, EStdKeyF4, }, // F4 + { {0x1b, 0x4f, 0x74, 0, 0, 0,}, EStdKeyDevice3, }, // F5 gives S60 centre press + { {0x1b, 0x4f, 0x75, 0, 0, 0,}, EStdKeyDevice0, }, // F6 gives S60 left softkey + { {0x1b, 0x4f, 0x76, 0, 0, 0,}, EStdKeyDevice1, }, // F7 gives S60 right softkey + { {0x1b, 0x4f, 0x6c, 0, 0, 0,}, EStdKeyApplication0, }, // F8 gives S60 application softkey + { {0x1b, 0x4f, 0x77, 0, 0, 0,}, EStdKeyF9, }, // F9 + { {0x1b, 0x4f, 0x78, 0, 0, 0,}, EStdKeyF10, }, // F10 + + { {0x1b, 0x5b, 0x41, 0, 0, 0,}, EStdKeyUpArrow, }, // Arrow keys + { {0x1b, 0x5b, 0x42, 0, 0, 0,}, EStdKeyDownArrow, }, // Arrow keys + { {0x1b, 0x5b, 0x43, 0, 0, 0,}, EStdKeyRightArrow, }, // Arrow keys + { {0x1b, 0x5b, 0x44, 0, 0, 0,}, EStdKeyLeftArrow, }, // Arrow keys + + // Four escape codes in a row that completes a sequence + { {0x1b, 0x5b, 0x31, 0x7e, 0, 0,}, EStdKeyHome, }, // Home key + { {0x1b, 0x5b, 0x34, 0x7e, 0, 0,}, EStdKeyEnd, }, // End key + { {0x1b, 0x5b, 0x35, 0x7e, 0, 0,}, EStdKeyPageUp, }, // Page Up key + { {0x1b, 0x5b, 0x36, 0x7e, 0, 0,}, EStdKeyPageDown, }, // Page down key + { {0x1b, 0x5b, 0x32, 0x7e, 0, 0,}, EStdKeyInsert, }, // Page down key + + // Five escape codes in a row that completes a sequence + { {0x1b, 0x5b, 0x32, 0x33, 0x7e, 0,}, EStdKeyF11, }, // F11 + { {0x1b, 0x5b, 0x32, 0x34, 0x7e, 0,}, EStdKeyF12, }, // F12 + + // end of table - should be all zeros + { {0, 0, 0, 0, 0, 0,}, 0, } +}; + +TSerialKeyboard::TSerialKeyboard() + : iKeyDfc( KeyDfcFn, this, Kern::DfcQue0(), 1 ), iSeqNum(0) + { + for (TUint i=0; iiBase = (TUint8*)base; + iUart->SetIER(0); + iUart->SetLCR(0); + iUart->SetFCR(0); + iUart->SetMCR(0); + } + else + return KErrNoMemory; + + iInterrupt=Interrupt::Bind(KIntIdUart0+iKeyboardPort,Isr,this); + if (iInterrupt<0) + { + delete iUart; + return iInterrupt; + } + + iUart->SetLCR(K16550LCR_Data8|K16550LCR_DLAB); + iUart->SetBaudRateDivisor((baud==230400) ? KBaudRateDiv_230400 : KBaudRateDiv_default); + iUart->SetLCR(K16550LCR_Data8); + iUart->SetFCR(K16550FCR_Enable|K16550FCR_RxReset|K16550FCR_TxReset|K16550FCR_RxTrig8); + iUart->SetIER(K16550IER_RDAI);// enable receiving data + + Interrupt::Enable(iInterrupt); + + return KErrNone; + } + + +void TSerialKeyboard::Isr( TAny* aPtr ) + // + // Interrupt service routine. Called when we receive an interrupt + // on the IRQ line it is bound to. If it's a receive, queues DFC + // to post the event into the event queue. + // + { + TSerialKeyboard* self = (TSerialKeyboard*)aPtr; + T16550Uart& u=*(self->iUart); + + TUint isr=u.ISR(); + if (isr & K16550ISR_NotPending) + return; + isr&=K16550ISR_IntIdMask; + + if (isr==K16550ISR_RDAI || isr==K16550ISR_RLSI) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("TSerialKeyboard::Isr:RHR")); + TUint ch=u.RxData(); + if (ch==31) + __crash(); // CTRL-? = instant death + if (self->iSeqNum < maxSeq) + { + self->iCode[self->iSeqNum] = ch; + self->iSeqNum++; + self->iKeyDfc.Add(); + Interrupt::Disable(self->iInterrupt); // Can only handle one char at a time + } + } + } + +void TSerialKeyboard::KeyDfcFn( TAny* aPtr ) + // + // DFC function. Just calls inline function KeyDfc() + // + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("TSerialKeyboard::KeyDfcFn")); + ((TSerialKeyboard*)aPtr)->KeyDfc(); + } + +void TSerialKeyboard::AddConvertedEvent(TUint aKey) + { + // split aKey into keycode and shift, func, ctrl status + TBool isShifted = ISSHIFTED(aKey); + TBool isFunced = ISFUNCED(aKey); + TBool isCtrled = ISCTRLED(aKey); + TUint8 stdKey = STDKEY(aKey); + + // post it as a sequence of events + TRawEvent e; + if (isShifted) + { + e.Set(TRawEvent::EKeyDown,EStdKeyRightShift,0); + Kern::AddEvent(e); + } + if (isCtrled) + { + e.Set(TRawEvent::EKeyDown,EStdKeyLeftCtrl,0); + Kern::AddEvent(e); + } + if (isFunced) + { + e.Set(TRawEvent::EKeyDown,EStdKeyLeftFunc,0); + Kern::AddEvent(e); + } + + e.Set(TRawEvent::EKeyDown,stdKey,0); + Kern::AddEvent(e); + + e.Set(TRawEvent::EKeyUp,stdKey,0); + Kern::AddEvent(e); + + if (isFunced) + { + e.Set(TRawEvent::EKeyUp,EStdKeyLeftFunc,0); + Kern::AddEvent(e); + } + if (isCtrled) + { + e.Set(TRawEvent::EKeyUp,EStdKeyLeftCtrl,0); + Kern::AddEvent(e); + } + if (isShifted) + { + e.Set(TRawEvent::EKeyUp,EStdKeyRightShift,0); + Kern::AddEvent(e); + } + } + +void TSerialKeyboard::AddUnconvertedEvent(TUint aKey) + { + TUint16 convertedKey = convertCodeSerial[aKey]; + AddConvertedEvent(convertedKey); + } + +inline void TSerialKeyboard::KeyDfc() + // + // Processes received characters + // + { + __KTRACE_OPT(KEXTENSION, Kern::Printf("KEY: iSeqNum=%x, key=%x", iSeqNum, iCode[iSeqNum-1])); + + switch (iSeqNum) + { + case 1: + if (iCode[0] != EEscapingStart) + { + // Unknown escape sequence - just pass chars as normal events + AddUnconvertedEvent(iCode[0]); + iSeqNum = 0; + } + break; + case 2: + if ((iCode[1] != EEscapingType1) && iCode[1] != EEscapingType2) + { + // Unknown escape sequence - just pass chars as normal events + AddUnconvertedEvent(iCode[0]); + AddUnconvertedEvent(iCode[1]); + iSeqNum = 0; + } + break; + case 3: + case 4: + case 5: + { + TUint escCodeindex = 0; // index into the escape code list + TUint seqIndex = 0; // index into the current code sequence + TUint bestMatch = 0; // keep a track of the best number of matches so far + while (escapeCodes[escCodeindex].seq[0] != 0) + { + for (seqIndex = 0; seqIndex bestMatch) + { + bestMatch = seqIndex; + } + if (escapeCodes[escCodeindex].seq[seqIndex] == 0) + { + AddConvertedEvent(escapeCodes[escCodeindex].convertedCode); + iSeqNum = 0; + break; // out of while loop + } + escCodeindex++; + } + + if ( (bestMatch < iSeqNum) // if we couldn't match all numbers in the sequence so far, this must not be a valid sequence + || (iSeqNum == maxSeq) // if we reached the max number of codes in a sequence, this must also not be a valid sequence + ) + { + if (escapeCodes[escCodeindex].seq[0] == 0) + { + // Unknown escape sequence - just pass chars as normal events + for (TUint i=0; i < iSeqNum; i++) + { + AddUnconvertedEvent(iCode[i]); + } + } + iSeqNum = 0; + } + } + break; + default: + // Should never reach here! + iSeqNum = 0; + break; + }; + Interrupt::Enable(iInterrupt); // Can handle new chars now + } /* end of function - KeyDfc - */ + +// +// Kernel Extension entry point +// +DECLARE_STANDARD_EXTENSION() + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Starting keyboard driver")); + + // create keyboard driver + TInt r=KErrNoMemory; + TSerialKeyboard* keyboard = new TSerialKeyboard; + if ( keyboard ) + { + r=keyboard->Create(); + } + + __KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r)); + return r; + } diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/uart/vserialkeyb.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/uart/vserialkeyb.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\uart\vserialkeyb.h +* Header for serial keyboard driver +* +*/ + + + +#ifndef __VSERIALKEYB_H__ +#define __VSERIALKEYB_H__ + +const TUint maxSeq = 5; + + +class TSerialKeyboard +{ +public: + TSerialKeyboard(); + TInt Create(); + static void Isr(TAny* aPtr); + +private: + static void KeyDfcFn(TAny* aPtr); + inline void KeyDfc(); + void AddConvertedEvent(TUint aKey); + void AddUnconvertedEvent(TUint aKey); + TInt GetSerialPort(TUint& aBaud); + + enum TState + { + ENormal, + EEscapingStart = 0x1b, + EEscapingType1 = 0x4f, + EEscapingType2 = 0x5b, + }; +private: + TDfc iKeyDfc; + TInt iKeyboardPort; + + TUint iSeqNum; + TUint iCode[maxSeq]; + + TInt iInterrupt; + T16550Uart* iUart; +}; + + +#endif /* __VSERIALKEYB_H__ */ diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/uart/vserialkeyb.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/uart/vserialkeyb.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp/uart/uart.mmp +* The extension enables keyboard input via the debugport UART connection +* +*/ + + + +/** + @file +*/ + +#include +#include "kernel/kern_ext.mmh" + +USERINCLUDE ../ +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +library VariantTarget(kanaviengine,lib) VariantTarget(ecust,lib) + +target VariantTarget(vserialkeyb,dll) +targettype kext + +sourcepath . +source vserialkeyb.cpp uart16550_ne.cia vserialkeybport.cpp + + +deffile ../../../../../os/kernelhwsrv/kernel/eka/~/empty.def + +uid 0x1000008d 0x100039e8 +romtarget ekeyb.dll +capability all +VENDORID 0x70000001 + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/uart/vserialkeybport.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/uart/vserialkeybport.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\uart\vserialkeyb.cpp +* Serial keyboard driver +* +*/ + + +/** + @file + @internalTechnology +*/ + +#include +#include +#include +#include "../naviengine.h" +#include +#include "uart16550_ne.h" +#include "vserialkeyb.h" + +TInt TSerialKeyboard::GetSerialPort(TUint& aBaud) + { + // For non-BootLoader images, set the debug port and serial port to be the same port + aBaud = 115200; + TInt r = Kern::SuperPage().iDebugPort; + if (r==0x100 || r==0x101) + r &= 0xff, aBaud = 230400; + return r; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/upd35001_timer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/upd35001_timer.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + + + +#ifndef __UPD35001_TIMER_H__ +#define __UPD35001_TIMER_H__ +#include + +struct NETimer + { + static inline NETimer& Timer(TUint a) { return *(NETimer*)(KHwTimersBase + (a<<10)); } + volatile TUint32 iTimerCount; /* counter register */ + volatile TUint32 iTimerCtrl; /* control register */ + volatile TUint32 iTimerReset; /* counter resets to zero upon reaching this value */ + volatile TUint32 iGTOPulseStart; /* output pulse starts at this value */ + volatile TUint32 iGTOPulseEnd; /* output pulse ends at this value */ + volatile TUint32 iGTICtrl; /* input capture mode control */ + volatile TUint32 iGTIRisingEdgeCapture; /* count captured at rising edge */ + volatile TUint32 iGTIFallingEdgeCapture; /* count captured at falling edge */ + volatile TUint32 iGTInterrupt; /* interrupt flags */ + volatile TUint32 iGTInterruptEnable; /* interrupt enable mask */ + volatile TUint32 iPrescaler; /* prescaler control */ + }; + +const TUint32 KNETimerCtrl_CAE = 0x00000001u; /* Count up enable (held static until set) */ +const TUint32 KNETimerCtrl_CE = 0x00000002u; /* Counter enable (held at 0 until set) */ +const TUint32 KNETimerCtrl_GTOEnable = 0x00000004u; /* GTO output enable */ + +const TUint32 KNETimerGTICtrl_FAL_M = 0x00000001u; +const TUint32 KNETimerGTICtrl_FAL_C = 0x00000002u; +const TUint32 KNETimerGTICtrl_RIS_M = 0x00000004u; +const TUint32 KNETimerGTICtrl_RIS_C = 0x00000008u; +const TUint32 KNETimerGTICtrl_FilterMask = 0xfffffff0u; +const TUint32 KNETimerGTICtrl_FilterShift = 4; + +const TUint32 KNETimerGTIInt_GTIFI = 0x00000001u; /* interrupt detected on falling edge of GTI */ +const TUint32 KNETimerGTIInt_GTIRI = 0x00000002u; /* interrupt detected on rising edge of GTI */ +const TUint32 KNETimerGTIInt_GTOFI = 0x00000004u; /* interrupt detected on falling edge of GTO */ +const TUint32 KNETimerGTIInt_GTORI = 0x00000008u; /* interrupt detected on rising edge of GTO */ +const TUint32 KNETimerGTIInt_TCI = 0x00000010u; /* interrupt detected on timer counter reset */ +const TUint32 KNETimerGTIInt_All = 0x0000001fu; /* mask to clear all pending interrupts */ + +const TUint32 KNETimerGTIIntE_GTIFE = 0x00000001u; /* interrupt enabled on falling edge of GTI */ +const TUint32 KNETimerGTIIntE_GTIRE = 0x00000002u; /* interrupt enabled on rising edge of GTI */ +const TUint32 KNETimerGTIIntE_GTOFE = 0x00000004u; /* interrupt enabled on falling edge of GTO */ +const TUint32 KNETimerGTIIntE_GTORE = 0x00000008u; /* interrupt enabled on rising edge of GTO */ +const TUint32 KNETimerGTIIntE_TCE = 0x00000010u; /* interrupt enabled on timer counter reset */ + +const TUint32 KNETimerPrescaleBy1 = 0x00000001u; +const TUint32 KNETimerPrescaleBy2 = 0x00000002u; +const TUint32 KNETimerPrescaleBy4 = 0x00000004u; +const TUint32 KNETimerPrescaleBy8 = 0x00000008u; +const TUint32 KNETimerPrescaleBy16 = 0x00000010u; +const TUint32 KNETimerPrescaleBy32 = 0x00000020u; + +#endif + + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/usbcc.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/usbcc.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp/usbcc.mmp +* +*/ + + + +#include +#include "kernel/kern_ext.mmh" + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + +target VariantTarget(usbcc,dll) +targettype kext +linkas usbcc.dll +noexportlibrary + +USERINCLUDE traces_usbcc + +sourcepath ../../../../os/kernelhwsrv/kernel/eka/drivers/usbcc +source chapter9.cpp +source descriptors.cpp +source misc.cpp +source ps_usbc.cpp +source queue.cpp + +sourcepath . +source pa_usbc.cpp + +library dma2.lib +library VariantTarget(kanaviengine,lib) + +deffile ../../../../os/kernelhwsrv/kernel/eka/~/usbcc.def + +epocallowdlldata + +capability all +uid 0x100039d0 0x1000015f +VENDORID 0x70000001 + +MACRO DMA_APIV2 diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/variant_timestamp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/variant_timestamp.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* The frequency of the system timestamp counter in Hz +* The timestamp counter is a 64 bit value which is required to increment at a +* constant rate of at least 1MHz and not to wrap in any reasonable amount of time. +* +*/ + + + + + +const TUint32 KTimestampFrequency = 66666667u; + +#ifdef __DEFINE_NKERN_TIMESTAMP_ASM__ +/* If NKern::Timestamp() is written in assembler define it here +*/ + +EXPORT_C __NAKED__ TUint64 NKern::Timestamp() + { + // Return a 64 bit high resolution timestamp count + // Timer 1 counts from 00000000 to FFFFFEFF and then wraps back to 0 + // Timer 2 counts from 00000000 to FFFFFFFF and then wraps back to 0 + // Both timers increment at 66.667MHz (15ns period) + // Algorithm: + // volatile TUint32 t2 = Timer2Count; // must read t2 first + // volatile TUint32 t1 = Timer1Count; + // TUint32 n = (t1-t2)>>8; // number of times T1 has wrapped + // return t1 + n * 0xFFFFFF00; + + asm("ldr r3, 1f "); // r3 = address of T1 counter + asm("mrs r12, cpsr "); + __ASM_CLI(); // interrupts off + asm("ldr r1, [r3, #0x400] "); // r1 = t2 + asm("ldr r0, [r3] "); // r0 = t1 + asm("msr cpsr, r12 "); // restore interrupts + asm("sub r1, r0, r1 "); // t1-t2 + asm("mov r1, r1, lsr #8 "); // n = (t1-t2)>>8, now have r1:r0 = 2^32*n + t1 + asm("subs r0, r0, r1, lsl #8 "); // subtract 256*n + asm("sbcs r1, r1, #0 "); // propagate borrow + __JUMP(,lr); + + asm("1: "); +#ifdef __MEMMODEL_DIRECT__ + asm(".word 0x18036400 "); // address of timer 1 counter +#else + asm(".word 0xC6003400 "); // address of timer 1 counter +#endif + } + +#endif + +#ifdef __DEFINE_NKERN_TIMESTAMP_CPP__ +/* If NKern::Timestamp() is written in C++ define it here +*/ +#endif + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/watchdog.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/watchdog.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,136 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\naviengine.cpp +* +*/ + + + +#include +#include "watchdog.h" + +const TInt KWatchdogTimeoutSecs = 5; // the period, in seconds, that the watchdog timer will expire + +// +// Pat the watchdog to prevent the board from resetting +// +void TNaviEngineWatchdog::WatchdogTimer(TAny* aPtr) + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("watchdogTimer expired")); + //Kern::Printf("watchdogTimer expired"); + + TNaviEngineWatchdog *pDog = (TNaviEngineWatchdog *) aPtr; + + // Pat the Dog now to give us the full period to respond with the timer + AsspRegister::Write32(KHwWatchdog_WDTINT, 1); + + // Now queue the timer again so that we can pat it next time around + pDog->iWatchdogTimer.Again(NKern::TimerTicks(pDog->iWatchdogTimerPeriodMs)); + } + + + +// +// Constructor +// +// We only really need the constructor to create the timer instance. +// +TNaviEngineWatchdog::TNaviEngineWatchdog() : + iWatchdogTimer(WatchdogTimer,this) + { + } + + + + +// Destructor should never be called +TNaviEngineWatchdog::~TNaviEngineWatchdog() + { + __crash(); + } + + + + +/** +Perform hardware-dependent initialisation + +Called by platform independent layer +*/ +TInt TNaviEngineWatchdog::Create() + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("TNaviEngineWatchdog::Create")); + //Kern::Printf("TNaviEngineWatchdog::Create"); + SetTimer(KWatchdogTimeoutSecs); + return KErrNone; + } + + +// +// Enable/disable the external watchdog timer (eWDT). +// +void TNaviEngineWatchdog::SetTimer(TUint aTimeoutInSeconds) + { + __KTRACE_OPT(KHARDWARE, Kern::Printf(">TNaviEngine::SetWatchdogTimer timeout=%d seconds", aTimeoutInSeconds)); + //Kern::Printf(">TNaviEngine::SetWatchdogTimer timeout=%d seconds", aTimeoutInSeconds); + + // Disable eWDT + AsspRegister::Write32(KHwWatchdog_WDTCNT, 0); + + // If only disabling then we're done + if (aTimeoutInSeconds > 0) + { + // Set the WTD period to something very near the required number + // of seconds (this assumes a 66.666MHz clock) + AsspRegister::Write32(KHwWatchdog_WDTSET, (aTimeoutInSeconds*63)<<20); + AsspRegister::Write32(KHwWatchdog_WDTTIM, 0); + + // Enable eWDT - start counting + AsspRegister::Write32(KHwWatchdog_WDTCNT, 1); + + // Pat the Dog now to give us the full period to respond with the timer + AsspRegister::Write32(KHwWatchdog_WDTINT, 1); + + // We have to decide how often to pat the dog, in seconds. + // The board will flag a warning after aTimeoutInSeconds, and reset after a further aTimeoutInSeconds. + // So we have to fire the watchdog at least every aTimeoutInSeconds to prevent the warning + // I've decided that we'll fire 500ms before the alarm to be sure we've patted the dog in time + __KTRACE_OPT(KHARDWARE, Kern::Printf("TNaviEngine::SetWatchdogTimer kicking off a timer...")); + //Kern::Printf("TNaviEngine::SetWatchdogTimer kicking off a timer..."); + + iWatchdogTimerPeriodMs = ((aTimeoutInSeconds * 1000) - 500); + iWatchdogTimer.OneShot(NKern::TimerTicks(iWatchdogTimerPeriodMs)); + } + } + + +DECLARE_STANDARD_EXTENSION() + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Watchdog: Starting timer service")); + //Kern::Printf("Watchdog: Starting timer service"); + + // create the watchdog handler + TInt r=KErrNoMemory; + TNaviEngineWatchdog* pH=new TNaviEngineWatchdog; + if (pH) + { + r=pH->Create(); + } + + __KTRACE_OPT(KEXTENSION,Kern::Printf("Watchdog: Returns %d",r)); + //Kern::Printf("Watchdog: Returns %d",r); + return r; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/naviengine_assp/watchdog.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/naviengine_assp/watchdog.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* naviengine_assp\naviengine.h +* Definitions for NE1_TBVariant ASSP +* +*/ + + + + + +#ifndef __A32WATCHDOG_H__ +#define __A32WATCHDOG_H__ +#include +#include +#include +#include +#include + + + +class TNaviEngineWatchdog + { +public: + TNaviEngineWatchdog(); + virtual ~TNaviEngineWatchdog(); // To shut up gcc98r2 + virtual TInt Create(); + + /** + * Enable/disable external watchdog timer (eWDT) + */ + void SetTimer (TUint aTimeoutInSeconds); + static void WatchdogTimer (TAny* aPtr); +private: + NTimer iWatchdogTimer; // Timer the kernel will fire to pat the dog + TUint iWatchdogTimerPeriodMs; // the period of the timer that pats the dog, note this should be LESS than the actual watchdog timeout + }; + +#endif // __A32WATCHDOG_H__ diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/bld.inf Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,138 @@ +/* +* Copyright (c) 1998-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/bld.inf +* Bld.inf for Flexible, Multiple and Direct MM common binaries +* +*/ + + +#ifndef NO_GCCXML +#define NO_GCCXML +#endif + +#include "../naviengine_assp/naviengine.inf" + +PRJ_PLATFORMS +ARM4 ARMV5 +ARM4SMP ARMV5SMP + + +PRJ_EXPORTS + +hcr/hcrconfig.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ne1_tb/) +hcr/hcrconfig_mha.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ne1_tb/) +inc/iolines.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ne1_tb/) +inc/mconf.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ne1_tb/) +inc/variantmediadef.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ne1_tb/) + +ne1_tb.oby /epoc32/rom/include/ // +rom/base_ne1_tb.iby /epoc32/rom/include/ // +rom/naviengine.oby /epoc32/rom/include/ // +rom/header.iby /epoc32/rom/ne1_tb/ // +rom/kernel.iby /epoc32/rom/ne1_tb/ // +nand/variant_nand_plat.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ne1_tb/) +inc/nand_fbr_offset.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ne1_tb/) + +estart/estart.txt /epoc32/rom/ne1_tb/ +estart/estarttechview.txt /epoc32/rom/ne1_tb/ + +nandboot/quicknand.bat /epoc32/rom/ne1_tb/ +nandboot/nandtest_load_rel_autoexec.bat /epoc32/rom/ne1_tb/ + +rom/ne1usbhost.iby /epoc32/rom/include/ + + +#if !defined(GCCXML) || !defined(NO_GCCXML) + +PRJ_MMPFILES + +#ifdef SMP +../../../../os/kernelhwsrv/kernel/eka/nkernsmp/nk_exe +../../../../os/kernelhwsrv/kernel/eka/nkernsmp/nkern_sa +#else +../../../../os/kernelhwsrv/kernel/eka/nkern/nk_exe +../../../../os/kernelhwsrv/kernel/eka/nkern/nkern_sa +#endif + +../../../../os/kernelhwsrv/kernel/eka/drivers/medint/medint +../../../../os/kernelhwsrv/kernel/eka/drivers/trace/btracex + +gpio +variant +watchdog +monitor +//datx +lcdgce +xyin +power +//serialno + +// TO DO: (mandatory) +// There are two sample keyboard drivers; one is polled and the other interrupt-driven. +// Need to comment out the one that is not appropriate for the hardware +key_int +key + +medlffs +soundsc +soundsc_v2 +//epbus +//exbusab +enet +resmanpsl +sdcontroller +sdcontroller_v2 +i2s +keypad +rebootdrv +csi +csi_ctrless + +// Hardware Configuration Repository +hcr/hcr + +#ifndef SMP +// Keyboard translation tables (user side) +keymap + +// Customized ESTART (user side) +estart + + +#include "memmodel_bld.inf" + +// Make the HAL +PRJ_EXTENSIONS +start extension base/config config + +option HALPATH $(EXTENSION_ROOT)/../../../../os/kernelhwsrv/halservices/hal/../. +option PREFIX _ne1_tb_ +option SOURCE $(EXTENSION_ROOT)/hal + +end + +PRJ_MMPFILES +hal/hal + +#endif // SMP + +// Build textshell image +PRJ_EXTENSIONS +start extension base/rom +option REE_TARGET ne1_tb +option TYPE tshell +end + +#endif // GCCXML diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/bmarm/csi_ctrless_masteronlyu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/bmarm/csi_ctrless_masteronlyu.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,5 @@ +EXPORTS + DfcFunc__20TIicBusSlaveCallbackPv @ 1 NONAME R3UNUSED ; TIicBusSlaveCallback::DfcFunc(void *) + New__17DCsiChannelMasteriQ214DIicBusChannel8TBusTypeQ214DIicBusChannel14TChannelDuplex @ 2 NONAME R3UNUSED ; DCsiChannelMaster::New(int, DIicBusChannel::TBusType, DIicBusChannel::TChannelDuplex) + __25DIicBusChannelMasterSlaveQ214DIicBusChannel8TBusTypeQ214DIicBusChannel14TChannelDuplexP20DIicBusChannelMasterP19DIicBusChannelSlave @ 3 NONAME ; DIicBusChannelMasterSlave::DIicBusChannelMasterSlave(DIicBusChannel::TBusType, DIicBusChannel::TChannelDuplex, DIicBusChannelMaster *, DIicBusChannelSlave *) + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/bmarm/csi_ctrless_nomodeu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/bmarm/csi_ctrless_nomodeu.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,4 @@ +EXPORTS + DfcFunc__20TIicBusSlaveCallbackPv @ 1 NONAME R3UNUSED ; TIicBusSlaveCallback::DfcFunc(void *) + __25DIicBusChannelMasterSlaveQ214DIicBusChannel8TBusTypeQ214DIicBusChannel14TChannelDuplexP20DIicBusChannelMasterP19DIicBusChannelSlave @ 2 NONAME ; DIicBusChannelMasterSlave::DIicBusChannelMasterSlave(DIicBusChannel::TBusType, DIicBusChannel::TChannelDuplex, DIicBusChannelMaster *, DIicBusChannelSlave *) + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/bmarm/csi_ctrless_slaveonlyu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/bmarm/csi_ctrless_slaveonlyu.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,5 @@ +EXPORTS + DfcFunc__20TIicBusSlaveCallbackPv @ 1 NONAME R3UNUSED ; TIicBusSlaveCallback::DfcFunc(void *) + New__16DCsiChannelSlaveiQ214DIicBusChannel8TBusTypeQ214DIicBusChannel14TChannelDuplex @ 2 NONAME R3UNUSED ; DCsiChannelSlave::New(int, DIicBusChannel::TBusType, DIicBusChannel::TChannelDuplex) + __25DIicBusChannelMasterSlaveQ214DIicBusChannel8TBusTypeQ214DIicBusChannel14TChannelDuplexP20DIicBusChannelMasterP19DIicBusChannelSlave @ 3 NONAME ; DIicBusChannelMasterSlave::DIicBusChannelMasterSlave(DIicBusChannel::TBusType, DIicBusChannel::TChannelDuplex, DIicBusChannelMaster *, DIicBusChannelSlave *) + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/bmarm/csi_ctrlessu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/bmarm/csi_ctrlessu.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,6 @@ +EXPORTS + DfcFunc__20TIicBusSlaveCallbackPv @ 1 NONAME R3UNUSED ; TIicBusSlaveCallback::DfcFunc(void *) + New__16DCsiChannelSlaveiQ214DIicBusChannel8TBusTypeQ214DIicBusChannel14TChannelDuplex @ 2 NONAME R3UNUSED ; DCsiChannelSlave::New(int, DIicBusChannel::TBusType, DIicBusChannel::TChannelDuplex) + New__17DCsiChannelMasteriQ214DIicBusChannel8TBusTypeQ214DIicBusChannel14TChannelDuplex @ 3 NONAME R3UNUSED ; DCsiChannelMaster::New(int, DIicBusChannel::TBusType, DIicBusChannel::TChannelDuplex) + __25DIicBusChannelMasterSlaveQ214DIicBusChannel8TBusTypeQ214DIicBusChannel14TChannelDuplexP20DIicBusChannelMasterP19DIicBusChannelSlave @ 4 NONAME ; DIicBusChannelMasterSlave::DIicBusChannelMasterSlave(DIicBusChannel::TBusType, DIicBusChannel::TChannelDuplex, DIicBusChannelMaster *, DIicBusChannelSlave *) + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/bmarm/gpio.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/bmarm/gpio.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,31 @@ +EXPORTS + UnbindInterrupt__4GPIOi @ 1 NONAME R3UNUSED ; GPIO::UnbindInterrupt(int) + ClearInterrupt__4GPIOi @ 2 NONAME R3UNUSED ; GPIO::ClearInterrupt(int) + DisableInterrupt__4GPIOi @ 3 NONAME R3UNUSED ; GPIO::DisableInterrupt(int) + DisableWakeup__4GPIOi @ 4 NONAME R3UNUSED ; GPIO::DisableWakeup(int) + EnableInterrupt__4GPIOi @ 5 NONAME R3UNUSED ; GPIO::EnableInterrupt(int) + EnableWakeup__4GPIOi @ 6 NONAME R3UNUSED ; GPIO::EnableWakeup(int) + GetDebounceTime__4GPIOiRi @ 7 NONAME R3UNUSED ; GPIO::GetDebounceTime(int, int &) + GetInputState__4GPIOiP13TGpioCallback @ 8 NONAME R3UNUSED ; GPIO::GetInputState(int, TGpioCallback *) + GetInputState__4GPIOiRQ24GPIO10TGpioState @ 9 NONAME R3UNUSED ; GPIO::GetInputState(int, GPIO::TGpioState &) + GetMaskedInterruptState__4GPIOiRi @ 10 NONAME R3UNUSED ; GPIO::GetMaskedInterruptState(int, int &) + GetOutputState__4GPIOiRQ24GPIO10TGpioState @ 11 NONAME R3UNUSED ; GPIO::GetOutputState(int, GPIO::TGpioState &) + GetPinBias__4GPIOiRQ24GPIO9TGpioBias @ 12 NONAME R3UNUSED ; GPIO::GetPinBias(int, GPIO::TGpioBias &) + GetPinDirection__4GPIOiRQ24GPIO14TGpioDirection @ 13 NONAME R3UNUSED ; GPIO::GetPinDirection(int, GPIO::TGpioDirection &) + GetPinIdleConfigurationAndState__4GPIOiRi @ 14 NONAME R3UNUSED ; GPIO::GetPinIdleConfigurationAndState(int, int &) + GetPinMode__4GPIOiRQ24GPIO9TGpioMode @ 15 NONAME R3UNUSED ; GPIO::GetPinMode(int, GPIO::TGpioMode &) + GetRawInterruptState__4GPIOiRi @ 16 NONAME R3UNUSED ; GPIO::GetRawInterruptState(int, int &) + IsInterruptEnabled__4GPIOiRi @ 17 NONAME R3UNUSED ; GPIO::IsInterruptEnabled(int, int &) + IsWakeupEnabled__4GPIOiRi @ 18 NONAME R3UNUSED ; GPIO::IsWakeupEnabled(int, int &) + SetDebounceTime__4GPIOii @ 19 NONAME R3UNUSED ; GPIO::SetDebounceTime(int, int) + SetInterruptTrigger__4GPIOiQ24GPIO21TGpioDetectionTrigger @ 20 NONAME R3UNUSED ; GPIO::SetInterruptTrigger(int, GPIO::TGpioDetectionTrigger) + SetOutputState__4GPIOiQ24GPIO10TGpioState @ 21 NONAME R3UNUSED ; GPIO::SetOutputState(int, GPIO::TGpioState) + SetOutputState__4GPIOiQ24GPIO10TGpioStateP13TGpioCallback @ 22 NONAME R3UNUSED ; GPIO::SetOutputState(int, GPIO::TGpioState, TGpioCallback *) + SetPinBias__4GPIOiQ24GPIO9TGpioBias @ 23 NONAME R3UNUSED ; GPIO::SetPinBias(int, GPIO::TGpioBias) + SetPinDirection__4GPIOiQ24GPIO14TGpioDirection @ 24 NONAME R3UNUSED ; GPIO::SetPinDirection(int, GPIO::TGpioDirection) + SetPinIdleConfigurationAndState__4GPIOii @ 25 NONAME R3UNUSED ; GPIO::SetPinIdleConfigurationAndState(int, int) + SetPinMode__4GPIOiQ24GPIO9TGpioMode @ 26 NONAME R3UNUSED ; GPIO::SetPinMode(int, GPIO::TGpioMode) + SetWakeupTrigger__4GPIOiQ24GPIO21TGpioDetectionTrigger @ 27 NONAME R3UNUSED ; GPIO::SetWakeupTrigger(int, GPIO::TGpioDetectionTrigger) + StaticExtension__4GPIOiiPvT3 @ 28 NONAME ; GPIO::StaticExtension(int, int, void *, void *) + BindInterrupt__4GPIOiPFPv_vPv @ 29 NONAME R3UNUSED ; GPIO::BindInterrupt(int, void (*)(void *), void *) + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/bmarm/lcdgcene1_tbu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/bmarm/lcdgcene1_tbu.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,4 @@ +EXPORTS + CreatePhysicalDevice__Fv @ 1 NONAME + RegisterCallback__16DLcdPowerHandlerP16TLcdUserCallBack @ 2 NONAME + DeRegisterCallback__16DLcdPowerHandlerP16TLcdUserCallBack @ 3 NONAME diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/bmarm/power.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/bmarm/power.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,6 @@ +EXPORTS + ResourceManager__22TNE1_TBPowerController @ 1 NONAME R3UNUSED ABSENT ; TNE1_TBPowerController::ResourceManager(void) + WakeupEvent__22TNE1_TBPowerController @ 2 NONAME R3UNUSED ; TNE1_TBPowerController::WakeupEvent(void) + EngageCore__22TNE1_TBPowerControlleriR15TRetireEngageCb @ 3 NONAME R3UNUSED ABSENT ; TNE1_TBPowerController::EngageCore(int, TRetireEngageCb &) + RetireCore__22TNE1_TBPowerControlleriR15TRetireEngageCb @ 4 NONAME R3UNUSED ABSENT ; TNE1_TBPowerController::RetireCore(int, TRetireEngageCb &) + IdleCount__22TNE1_TBPowerController @ 5 NONAME ; TNE1_TBPowerController::IdleCount diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/bmarm/variant.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/bmarm/variant.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,9 @@ +EXPORTS + VariantInitialise @ 1 NONAME + BaseLinAddress__7Variant @ 2 NONAME R3UNUSED ; Variant::BaseLinAddress(void) + MarkDebugPortOff__7Variant @ 3 NONAME R3UNUSED ; Variant::MarkDebugPortOff(void) + PowerReset__7Variant @ 4 NONAME R3UNUSED ; Variant::PowerReset(void) + Switches__7Variant @ 5 NONAME R3UNUSED ; Variant::Switches(void) + GetSerialNumber__13NE1_TBVariant @ 6 NONAME R3UNUSED ; NE1_TBVariant::GetSerialNumber(void) + SetSerialNumber__13NE1_TBVariantUl @ 7 NONAME R3UNUSED ; NE1_TBVariant::SetSerialNumber(unsigned long) + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/bootstrap/miniboot.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/bootstrap/miniboot.s Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,332 @@ +; +; Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +; All rights reserved. +; This component and the accompanying materials are made available +; under the terms of "Eclipse Public License v1.0" +; which accompanies this distribution, and is available +; at the URL "http://www.eclipse.org/legal/epl-v10.html". +; +; Initial Contributors: +; Nokia Corporation - initial contribution. +; +; Contributors: +; +; Description: +; \ne1_tb\bootstrap\miniboot.s +; Code to retrieve the core loader image from the NAND flash and +; run it. Expects that the system is in a state where NAND can be +; read and SDRAM can be written. +; See variant_bootstrap.inc for the variant specfic constants +; Where in RAM should the core loader be copied to (LINKBASE of coreldr) +; There is a companion to this value in the coreloader makefile, they must +; match! +; + + INCLUDE e32rom.inc + INCLUDE naviengine.inc + +KMinibootStackAddr EQU 0x820003FC +KRAMBase EQU 0x80000000 ; base of ram + +KNandPageSize EQU 2048 +KPageByteShift EQU 11 + +;Command Set Reg Bits +KNandBusyBit EQU 0x0100 +KNandPageReadBM EQU 0x0101 +KNandResetBM EQU 0x0106 + +;ECC Reg Bits +KNandECCDRC EQU 0x0080 + +; NAND Register Addresses +KNandDataWndw EQU 0x18019000; +KNandPgeAdr1Reg EQU 0x18019840; +KNandPgeAdr2Reg EQU 0x18019842; +KNandPgeAdrMskReg0 EQU 0x18019844; +KNandPgeAdrMskReg1 EQU 0x18019846; +KNandPgeAdrMskReg2 EQU 0x18019848; +KNandPgeAdrMskReg3 EQU 0x1801984A; +KNandCmdSetReg EQU 0x1801984E; +KNandDataAreaECCReg EQU 0x18019850; +KNandROMTypeSetup1 EQU 0x18019852; +KNandROMTypeSetup2 EQU 0x18019854; +KNandChipSelect EQU 0x18019856; + + +; Which page in NAND holds the Coreldr image +KSymbianCoreldrPage EQU 1 ; +KSymbianCoreldrSizePages EQU 64 ; 64 * 2048B = 128KB + +; Export the miniboot's only entry point + EXPORT GetCoreldr + +; +; Area definition for ARMLD linker +; + AREA |Boot$$Code|, CODE, READONLY, ALIGN=6 + +;****************************************************************************** +; Boot Entry point for bootloader's miniboot code +; +; Always runs +; after the bootloader has initialised the memory subsystem +; with the SRAM/SDRAM devices available. (RAM >0x8000.0000) +; +; Tasks +; Confirm NAND device is as expected +; read TOC structure at the start of the NAND (in page 0) +; search TOC array for coreloader image entry +; load coreloader sized image from NAND offset (from TOC) +; jump to coreloader entry point +; +;****************************************************************************** + +GetCoreldr + ; create a stack so that we can use ordinary function calls + ldr r13, =KMinibootStackAddr + + ; RESET_NAND + LDR r0, =KNandResetBM ; CMD_RESET | XROMC_BUSY_BIT_MASK + LDR r4, =KNandCmdSetReg ; XROMC + STRH r0, [r4] + + ; POLLED_WAIT_FOR_RDY +1 + LDR r4, =KNandCmdSetReg + LDRH r0, [r4] ; Get contents of Command setup register + TST r0, #KNandBusyBit + BNE %B1 + + ; Start from a clean, ready system state + ; INIT_PNL_DEVICE + LDR r0, =0xF000 ;Unmask address for XROMM0-3 + LDR r4, =KNandPgeAdrMskReg0 + STRH r0, [r4] + + LDR r4, =KNandPgeAdrMskReg1 + STRH r0, [r4] + + LDR r4, =KNandPgeAdrMskReg2 + STRH r0, [r4] + + LDR r4, =KNandPgeAdrMskReg3 + STRH r0, [r4] + + ;Configure the NAND Type + ;CS1 NAND Config: 8bit, 2K + ;CS2 NAND Config: 8bit, 2K + LDR r0, =0x0101 + LDR r4, =KNandROMTypeSetup1 + STRH r0, [r4] + ;CS3 NAND Config: 8bit, 2K + LDR r0, =0x01 + LDR r4, =KNandROMTypeSetup2 + STRH r0, [r4] + + ; Select chipset 0 to be used (navi supports upto 4 NAND chips) + LDR r0, =0x0000 ;Select ChipSet 0 + LDR r4, =KNandChipSelect + STRH r0, [r4] + + LDR r4,=KNandDataAreaECCReg + LDRH r0, [r4] ; get contents of register + BIC r0, r0, #0x1 + STRH r0, [r4] + + + ; Normally Read the device ID and confirm nand device is as expected + ; NAND Controller on NaviEngine doesn't allow the Device id to be read + + bl readhdr16 ; read header of 16bit device + ; Readhdr16 -> parse_header -> find/load Symbian coreldr -> run coreldr + + +;------------------------------------------------------------------------ +; +; strcmp - bytewise compare of two strings +; r0->string A +; r1->string B +; r3->size of string A +; +; if string A == string B return 0 in r0 +; else returns non zero in r0 +; +;------------------------------------------------------------------------ +strcmp ROUT + stmfd r13!, {r4-r6,lr} + + mov r4, r0 + mov r5, r1 + mov r6, r3 + +strloop + ldrb r2, [r4], #1 + ldrb r3, [r5], #1 + + subs r0, r2, r3 + cmp r2, #0 + beq strreturn + subs r6, r6, #1 + bne strloop +strreturn + ldmfd r13!, {r4-r6,pc} + + +;--------------------------------------------------------------------------------- +; readpage16 +; +; read 1 page (2048KB) of NAND device, +; starting at page (r0) +; put data into address (r1) +; +;--------------------------------------------------------------------------------- +readpage16 ROUT + stmfd r13!, {r4-r7,lr} + + ; set the page start addresss [r0] + ; need multiple by page size to get correct address + MOV r6, #KNandPageSize ; 2048 + + ;Set Address Reg1 (lower range) + MUL r7, r0, r6 + LDR r4, =KNandPgeAdr1Reg + STRH r7, [r4] + + ;Set Address Reg2 (upper range) + ;MUL r7, r0, r6 + LSR r7, r7, #0x10; + LDR r4, =KNandPgeAdr2Reg + STRH r7, [r4] + + ; Issue Read Command + LDR r5, =KNandPageReadBM ; CMD_READ | XROMC_BUSY_BIT_MASK + LDR r4, =KNandCmdSetReg ; XROMC + STRH r5, [r4] + + ; Poll Busy Bit +1 + LDRH r5, [r4] ; Get contents of Command setup register + TST r5, #KNandBusyBit + BNE %B1 + + ; Poll status DRC(Data Read Complete) +2 + LDR r4, =KNandDataAreaECCReg + LDRH r5, [r4] ; Get contents of ECC register + TST r5, #KNandECCDRC + BNE %B2 + + ;Copy page (2048) into address [r1] + LDR r4, =KNandDataWndw + MOV r6, #KNandPageSize ; 2048 +read + LDRH r5, [r4] + STRH r5, [r1], #2 ; save at target + ADD r4, r4, #2 ; move data wndw pointer + SUBS r6, r6, #2 ; end of page? + BNE read ; no => copy some more ;) + + ldmfd r13!, {r4-r7,pc} ; yes, return + +;----------------------------------------------------------------------------------- +; readpages16 +; +; read pages of NAND, +; starting at page +; placing data starting at +; +;----------------------------------------------------------------------------------- +readpages16 ROUT + stmfd r13!, {r4-r6,lr} + mov r4, r0 + mov r5, r1 + mov r6, r2 +loop16 + bl readpage16 + subs r6, r6, #1 + ldmeqfd r13!, {r4-r6,pc} + add r0, r0, #1 + b loop16 + +;----------------------------------------------------------------------------------- +; +; readhdr16 +; +; Read the NAND header from flash into ram so it may be examined for a Symbian +; signature. +; +;----------------------------------------------------------------------------------- +readhdr16 + ; read the header of a 16b device + ;Print page + + ldr r0, =0x0 ; header pag + ldr r1, =KCoreLoaderAddress ; + bl readpage16 + + b parse_header + +;--------------------------------------------------------------------------- +; +; At this point the header buffer contains the first NAND page +; Determine whether the NAND device has been formatted according to the +; new style Symbian FBR layout +; +;--------------------------------------------------------------------------- + +parse_header + bl find_symbian_coreldr + cmp r0, #0 + beq load_symbian_coreldr + + ; Use a label rather than a SUB/PC as it makes a symbol for a debugger. +SymbianCoreldrNotFound + + b SymbianCoreldrNotFound ; spin forever + + ; NOTREACHED + +;--------------------------------------------------------------------------------- +; +; find_symbian_coreldr +; +; searches for the Symbian1 signature in the FBR then assumes +; that the coreldr will be stored in the 30 pages (15k) starting +; at page 4. +; +;--------------------------------------------------------------------------------- + +Symbian_Signature DCB "1naibmyS" +Symbian_Signature_size EQU 8 + + +find_symbian_coreldr ROUT + stmfd r13!, {r4,lr} + ldr r0, =KCoreLoaderAddress + add r0, r0, #4 ; signature at byte 4 in page 0 + ADR r1, Symbian_Signature + ldr r3, =Symbian_Signature_size + bl strcmp + ldmfd r13!, {r4,pc} + +;--------------------------------------------------------------------------------- +; +; load_symbian_coreldr +; +; Assumses Coreloader starts at page 1 and can be as big as 64 pages (128KB) +; +;--------------------------------------------------------------------------------- +load_symbian_coreldr ROUT + + mov r0, #KSymbianCoreldrPage + ldr r1, =KCoreLoaderAddress + mov r2, #KSymbianCoreldrSizePages + bl readpages16 + + ; restart CPUs, by calling restart vertor. + mov r0, #KtRestartReasonCoreLdr + add pc, r12, #TRomHeader_iRestartVector + + ; NOTREACHED + END diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/bootstrap/ne1_tb.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/bootstrap/ne1_tb.s Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,1040 @@ +; +; Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +; All rights reserved. +; This component and the accompanying materials are made available +; under the terms of "Eclipse Public License v1.0" +; which accompanies this distribution, and is available +; at the URL "http://www.eclipse.org/legal/epl-v10.html". +; +; Initial Contributors: +; Nokia Corporation - initial contribution. +; +; Contributors: +; +; Description: +; ne1_tb/bootstrap/ne1_tb.s +; NE1_TBVariant for platform specific boot code +; + + GBLL __VARIANT_S__ ; indicates that this is platform-specific code + GBLL __NE1_TB_S__ ; indicates which source file this is + + INCLUDE bootcpu.inc + INCLUDE arm_types.inc + INCLUDE naviengine.inc + + IF CFG_DebugBootRom + GBLL CFG_InitDebugPort + ENDIF + INIT_LOGICAL_SYMBOL CFG_InitDebugPort + + IF :DEF: CFG_AlternateEntryPoint; NOTE: Bootloader is defined by this macro + IMPORT GetCoreldr + ENDIF + +;******************************************************************************* +; +; Platform specific constant definitions + + IF :DEF: CFG_AlternateEntryPoint :LOR: CFG_MMDirect +RamBank0MaxSize EQU 0x08000000 ; for bootloader or direct, the upper half is reserverd for the image + ELSE +RamBank0MaxSize EQU 0x10000000 + ENDIF + +PrimaryRomBase EQU 0x00000000 +PrimaryRomSize EQU 0x04000000 +ExtensionRomBase EQU 0x08000000 +ExtensionRomSize EQU 0x00000000 + + +;******************************************************************************* + +; ASSP Specific constants + + IF :LNOT: CFG_MMDirect + +;Serial Ports Linear Addresses: + +Serial0LinBase EQU KPrimaryIOBase +Serial1LinBase EQU KPrimaryIOBase + (KHwUART1Phys - KHwUART0Phys) + + ENDIF + +;Serial Port Register Offsets +Serial_DLL EQU 0 +Serial_DLH EQU 4 +Serial_LCR EQU 0xc +Serial_THR EQU 0 +Serial_LSR EQU 0x14 + + + IF :LNOT: CFG_MMDirect + +SysCtrlUnitLinBase EQU KPrimaryIOBase + (0x1000*3)+0x1c00 + ; ... as the value in ne1_tb_bootloader\inc\bootloader_variantconfig.h + ENDIF + +;******************************************************************************* +; There are 4 red LEDs that can be controlled by a 16 bit register in the FPGA. +; Each LED has a bit in the register, where 0==off and 1==on +; We use each register to show the CPU status, where: +; off is "not started" +; on is "started" +; once the system is running, the OS may use the LEDs for other purposes +;******************************************************************************* +KHwFpgaLedsPhyicalBase EQU KHwFPGAPhys + KHoFpgaLeds; + + IF :LNOT: CFG_MMDirect +KHwFpgaLedsLinBase EQU KPrimaryIOBase + 0xB000 + KHoFpgaLeds; + ENDIF + + +;******************************************************************************* +; struct SSmrIF +; interface between Core Loader and Bootstrap +; See: bootstrap_smrif.h +;******************************************************************************* +SSmrIF_iNumOfShwPart EQU 0x00000000 +SSmrIF_iSmribSize EQU 0x00000004 +SSmrIF_iSmrBanks EQU 0x00000008 +SSmrIF_sz EQU 0x0000000c + + + +;******************************************************************************* +; + + AREA |Boot$$Code|, CODE, READONLY, ALIGN=6 + +; +;******************************************************************************* +; + + +;*************************************************************************************** +; Determine variant required when running on NaviEngine NE1-TB +; Enter with: +; R12 points to TRomHeader +; NO STACK +; R14 = return address (as usual) +; +; Return with: +; R10 = Super page address +;*************************************************************************************** +; +; The SuperPage is placed at the start of the free RAM. + EXPORT CalculateSuperPageAddress +CalculateSuperPageAddress + MOV r7, lr + ANDS r10, pc, #KHwDDR2RamBasePhys ; running from RAM? if not, r10=0 + MOVEQ r10, #KHwDDR2RamBasePhys ; if running from flash, super page is at base of RAM bank 0 + BLNE SetupSuperPageRunningFromRAM ; if running from RAM, super page goes after ROM image(s) + MOV lr, r7 + MOV pc, lr + +;******************************************************************************* +; Initialise Hardware +; Initialise CPU registers +; Determine the hardware configuration +; Determine the reset reason. If it is wakeup from a low power mode, perform +; whatever reentry sequence is required and jump back to the kernel. +; Set up the memory controller so that at least some RAM is available +; Set R10 to point to the super page or to a temporary version of the super page +; with at least the following fields valid: +; iBootTable, iCodeBase, iActiveVariant, iCpuId +; and optionally: +; iSmrData +; In debug builds initialise the debug serial port +; +; Enter with: +; R2 = value as at entry to ResetEntry, preserved unmodified +; R3 = value of cpsr on entry to ResetEntry +; R12 = points to TRomHeader +; NO STACK +; R14 = return address (as usual) +; +; Leave with : +; R10 = physical address of super page +; +; All registers may be modified by this call +; +;******************************************************************************* + EXPORT InitialiseHardware +InitialiseHardware ROUT + MOV r13, lr ; save return address + + MOV r8, r2 ; Preserve r2, r3 (cpsr) till later + MOV r9, r3 ; S/P initialisation by boot processor + + IF :DEF: CFG_AlternateEntryPoint; NOTE: Bootloader is defined by this macro + + LDR r1, =KHwSYSCTRLPhys + 0x00C ; Reset status + LDR r1, [r1] + ANDS r1, r1, #0x00030000 ; soft-reset or hot-reset? + BNE changed_wtop_mode + + LDR r1, =KHwSYSCTRLPhys + 0x11C ; WTOP + LDR r0, [r1] + ANDS r0, r0, #0xFFFFFFFE ; clear bit 0b to be normal mode + STR r0, [r1] + + LDR r1, =KHwSYSCTRLPhys + 0x00C ; Reset status + MOV r0, #0x00000001 + STR r0, [r1] ; soft reset is executed + +changed_wtop_mode + ; Fix the WFE JTAG problem: WFE operations disconnected the JTAG debugger + ; 0x18037d08 = 0; // SCU CPU status = 0 + LDR r0, =KHwSYSCTRLPhys + MOV r1, #0 + STR r1, [r0, #0x108] + + ARM_DSB + + ; 0xC0000008 = 0; // SCU CPU status = 0 + LDR r0, =KHwBaseMPcorePrivatePhys + MOV r1, #0 + STR r1, [r0, #0x08] + + ARM_DSB + + ; Check boot reason in the SCU Memo register + ; Using ADRL as when CFG_DebugBootRom defined, SysCtrlUnitPhysicalAdr + ; beyond range for an ADR instruction. + ADRL r1, SysCtrlUnitPhysicalAdr + LDR r1, [r1] + LDR r0, [r1] + + ; Check if miniboot has run, and we're ready for the coreldr + TST r0, #KtRestartReasonCoreLdr + MOVNE r5, #KCoreLoaderAddress ; Jump into coreldr, NO RETURN! + BNE all_cores_run_r5 + + TST r0, #KtRestartReasonBootRestart + BEQ check_cpu_id + MOV r5, #KRamTargetAddr + +all_cores_run_r5 + ; There is something for all cores to run (coreldr or new image) + ; at the address in r5. + ; But, before we start, we need to get CPU0 to initialise the ASSP + ; to make RAM accessible, and reset the Memo register. + ; Otherwise, if the board reboots again (eg. if the user presses the reset switch) + ; then the BootLoader will attempt to boot the RAM image again. And after the + ; reset switch, RAM is not longer valid. + + ; Is this the boot processor ? + MRC p15, 0, r0, c0, c0, 5 + ANDS r0, r0, #0x0f ; r0 = CPU number 0-3 + BNE skip_init_step ; Branch out if CPU != 0 (!= boot processor) + + ; Initialise RAM controller etc. Only if NOT running from RAM + CMP PC, #KHwDDR2RamBasePhys + BLLS AsspInitialiseHardware + + ; Set SCU Memo register using CPU0 + ADR r1, SysCtrlUnitPhysicalAdr + LDR r1, [r1] + MOV r0, #0 + STR r0, [r1] ; clear restart reason to 0 + +skip_init_step + LDR r0, =KHwSYSCTRLPhys + 0x014 ; Peripheral reset control + LDR r1, [r0] + CMP r1, #0 + BNE skip_init_step ; wait for AsspInitialiseHardware to complete + + MOV pc, r5 ; Jump into loaded code, NO RETURN! + + ENDIF + +check_cpu_id + ; Is this the boot processor ? + MRC p15, 0, r0, c0, c0, 5 + ANDS r0, r0, #0x0f ; r0 = CPU number 0-3 + BEQ IsBootProcessor ; Branch out if CPU 0 (= boot processor) + + ; No - this is an AP + IF SMP + LDR r11, =KHwBaseMPcorePrivatePhys ; r11 points to SCU + ADD r8, r11, #0x1000 ; Physical address of GIC Distributor + ADD r9, r11, #0x100 ; Physical address of GIC CPU Interface + B APResetEntry ; NO RETURN! + ELSE +1 + mov r0, #0 + mcr p15, 0, r0, c7, c0, 4 + B %BA1 ; NO RETURN! + ENDIF + + ; This is the boot processor +IsBootProcessor + ; Initialise RAM controller etc. Only if NOT running from RAM + CMP PC, #KHwDDR2RamBasePhys + BLLS AsspInitialiseHardware + + IF :DEF: CFG_AlternateEntryPoint; NOTE: Bootloader is defined by this macro + ; Check for Alternate boot reasons (other than KtRestartReasonBootRestart) + ADR r1, SysCtrlUnitPhysicalAdr + LDR r1, [r1] + LDR r0, [r1] + + TST r0, #KtRestartReasonNANDImage ; Check for specific nand boot restart reason + BNE GetCoreldr ; try booting from NAND flash, NO RETURN! + ENDIF + + ; Turn on LED for CPU 0 and turn off LEDs for CPU 1, 2, 3 + GET_ADDRESS r0, KHwFpgaLedsPhyicalBase, KHwFpgaLedsLinBase + ; r0 is the address of the 16bit LED register in FPGA, aka FLED + MOV r1, #KHtFpgaLed0 ; Turn on LED for CPU0 and turn off the other LEDs + STRH r1, [r0] ; write r1 back to the FLED register + + IF :DEF: CFG_USE_SHARED_MEMORY + ; Switch on Snoop Control Unit. + ; The whole procedure for switching to SMP is: + ; - Set SCU on. : Done here + ; - Disable INTs : Alreday disabled + ; - Flush DCache : See InitCpu + ; - Set SMP bit in AUX reg : See InitCpu + ; - Enable INTs : Later on + MOV r0, #KHwBaseMPcorePrivatePhys + MVN r1, #0 + STR r1, [r0, #0x0C] ; invalidate all SCU ways + LDR r1, [r0] + ORR r1, r1, #1 ; SCU Enable + ORR r1, r1, #0xFE ; Enable all aliases of everything + ORR r1, r1, #0x1F + STR r1, [r0] + ENDIF + + ADRL r1, ParameterTable ; pass address of parameter table + BL InitCpu ; initialise CPU/MMU registers, r0..r7 modified + + IF CFG_InitDebugPort + BL InitDebugPort ; r0..r2 modified + ENDIF + + +;;;;;;;;;;;; +; Put super page at end of SDRAM for now and set up the required super page values +;;;;;;;;;;; + +; LDR r10, =(KHwSdramBaseAddr+(KHwRamSizeMb<<20)-0x2000) + BL CalculateSuperPageAddress + + + LDR r7, =CFG_HWVD ; variant number from config.inc + STR r7, [r10, #SSuperPageBase_iActiveVariant] + + MOV r1, #0 + STR r1, [r10, #SSuperPageBase_iHwStartupReason] ; reset reason = 0 + + ADD r1, r10, #CpuPageOffset + STR r1, [r10, #SSuperPageBase_iMachineData] + + ADRL r0, BootTable + STR r0, [r10, #SSuperPageBase_iBootTable] ; set the boot function table + + STR r12, [r10, #SSuperPageBase_iCodeBase] ; set the base address of bootstrap code + + MRC p15, 0, r0, c0, c0, 0 ; read CPU ID from CP15 + STR r0, [r10, #SSuperPageBase_iCpuId] + + + ; Process SMRIB from pre-OS Loader and copy to CPU Page. + ; + ; r8 = r2 from ResetEntry = Address of block: <...> + ; r9 = r3 the CPSR from entry of ResetEntry + ; + ; SMRIB address in r2 only valid when cpsr (r3) shows ResetEntry entered + ; with System CPU mode set. Such a scenario can only be supported from + ; local media ROM boots. i.e. boot from NAND + ; + + AND r0, r9, #EMaskMode ; Check for System CPU mode + CMP r0, #ESystemMode + MVNNE r0, #0 ; Set iSmrData to KSuperPageAddressFieldUndefined when CPU + STRNE r0, [r10, #SSuperPageBase_iSmrData] ; not in system mode before + BNE NoSMRIB ; i.e. no SMRIB present/defined + + ; Proceed to copy SMRIB to Cpu Page at SP+CpuSmrTableOffset + + ADD r1, r10, #CpuSmrTableOffset ; Set the iSmrData member to the SMRIB address + STR r1, [r10, #SSuperPageBase_iSmrData] ; in the CpuPage, see bootdefs.h, space + ; for 8 SSmrBank records, max. Sets r1 for call to WordMove + + ; preparing r0, r2 for call to WordMove + LDR r0, [r8, #SSmrIF_iSmrBanks] ; Load SMR Banks starting address from SSmrIF::iSmrBanks + ; see kernboot.h + + LDR r2, [r8, #SSmrIF_iSmribSize] ; Load SMRIB size from SSmrIF::iSmribSize and validate, while + + DWORD r0, "Variant Bootstrap found SMRIB at" + DWORD r2, "With the size of the SMRIB being" + DWORD r1, "Will copy to " + + CMP r2, #SSmrBank_sz + FAULT LT ; Fault if SMRIB size < 16 + CMP r2, #CpuSmrTableTop-CpuSmrTableOffset-16 ; -16 to allow space for null entry, 7 entries allowed + FAULT GT ; Fault if SMRIB size > 112 + + BL WordMove ; r0=src addr, r1=dest addr, r2=bytes, modifies r0..r3 + ; No need to copy or add zero entry, Cpu page zerod already +NoSMRIB + + + MOV pc, r13 + ; END of InitialiseHardware() + + + +;******************************************************************************* +; Initialise Assp H/W (memory controllers) +; +; Enter with : +; R12 points to ROM header +; There is no valid stack +; +; Leave with : +; R0-R2 modified +; Other registers unmodified +;******************************************************************************* + EXPORT AsspInitialiseHardware +AsspInitialiseHardware ROUT + + ADR r0,Init_data +1 + LDR r1,[r0],#4 + LDR r2,[r0],#4 + CMP r1, #0 + BEQ %FT2 + STR r2,[r1] + B %BT1 +2 + MOV pc, r14 ; return + +Init_data +;*DDR2 Init + DCD 0x18021044,0x30022123 + DCD 0x18021058,0x00000001 + DCD 0x18021008,0x00000020 + +;*delay(Reset Status Register dummy write) + DCD 0x18037C0C,0x00000000 + DCD 0x18021008,0x10000004 + DCD 0x18021008,0x00010002 + DCD 0x18021008,0x00018002 + DCD 0x18021008,0x00008002 + DCD 0x18021008,0X1D480002 + DCD 0x18021008,0x10000004 + DCD 0x18021008,0x00000001 + DCD 0x18021008,0x00000001 + +;*delay(Reset Status Register dummy write) + DCD 0x18037C0C,0x00000000 + DCD 0x18037C0C,0x00000000 + DCD 0x18037C0C,0x00000000 + DCD 0x18021008,0x19480002 + DCD 0x18021008,0x01308002 + DCD 0x18021008,0x00000100 + DCD 0x18021040,0x1485A912 + DCD 0x18021034,0x00000121 + +;*SysCon Init +;* .word 0x18037C80,0x007F0103 + + DCD 0x18037C80,0x00000000 + +;*ExBus Init + DCD 0x1801A000,0x0000004A + DCD 0x1801A004,0x08000049 + DCD 0x1801A008,0x0600004E + DCD 0x1801A00C,0x0400004B + DCD 0x1801A010,0x1000004A + DCD 0x1801A014,0x1400000A + DCD 0x1801A020,0x10388E7F + DCD 0x1801A024,0x10388E7E + DCD 0x1801A028,0x10388E7E + DCD 0x1801A02C,0x10388E7F + DCD 0x1801A030,0x10388E7E + DCD 0x1801A034,0x10388E7E + +;*ExBus PCS5 UART-EX Init + DCD 0x14020003,0x00 + DCD 0x14020001,0x00 + DCD 0x14020002,0x07 + DCD 0x14020003,0x80 + DCD 0x14020000,0x1E + DCD 0x14020001,0x00 + DCD 0x14020003,0x03 + DCD 0x14020004,0x03 + +;*ExBus PCS5 CharLED + DCD 0x14000000,0x59 + DCD 0x14000001,0x45 + DCD 0x14000002,0x53 + DCD 0x14000003,0x21 + DCD 0x14000004,0x21 + DCD 0x14000005,0x20 + DCD 0x14000006,0x20 + DCD 0x14000007,0x20 + +;*ExBus PCS4 LED + DCD 0x10000030,0x00AA + + DCD 0x18037C14,0x00000000; reset release for all peripheral units + ; other cores are waiting for this, must be last + +;*End + DCD 0x0, 0x0 + + +;******************************************************************************* +; Notify an unrecoverable error during the boot process +; +; Enter with: +; R14 = address at which fault detected +; +; Don't return +;******************************************************************************* + EXPORT Fault +Fault ROUT + B BasicFaultHandler ; generic handler dumps registers via debug + ; serial port + + + + + +;******************************************************************************* +; Reboot the system +; This function assumes that CPU#0 is running !!! +; +; Enter with: +; R0 = reboot reason code +; +; Don't return (of course) +;******************************************************************************* + ALIGN 32, 0 + EXPORT RestartEntry +RestartEntry ROUT + + ; Save R0 parameter in HW dependent register which is preserved over reset + GET_ADDRESS r1, KHwSYSCTRLPhys, SysCtrlUnitLinBase + STR r0, [r1] + + ; Set SFTRSTP to reset all peripherals and all cores + MOV r0, #1 + STR r0, [r1, #0xC] + SUB pc, pc, #8 + +SysCtrlUnitPhysicalAdr + DCD KHwSYSCTRLPhys +LedPhysicalAdr + DCD 0x4010a06 + +;******************************************************************************* +; Get a pointer to the list of RAM banks +; +; The pointer returned should point to a list of {BASE; MAXSIZE;} pairs, where +; BASE is the physical base address of the bank and MAXSIZE is the maximum +; amount of RAM which may be present in that bank. MAXSIZE should be a power of +; 2 and BASE should be a multiple of MAXSIZE. The generic code will examine the +; specified range of addresses and determine the actual amount of RAM if any +; present in the bank. The list is terminated by an entry with zero size. +; +; The pointer returned will usually be to constant data, but could equally well +; point to RAM if dynamic determination of the list is required. +; +; Enter with : +; R10 points to super page +; R12 points to ROM header +; R13 points to valid stack +; +; Leave with : +; R0 = pointer +; Nothing else modified +;******************************************************************************* +GetRamBanks ROUT + ADR r0, %FT1 + MOV pc, lr +1 + DCD KHwDDR2RamBasePhys | RAM_VERBATIM, RamBank0MaxSize + DCD 0,0 ; terminator + + + + + +;******************************************************************************* +; Get a pointer to the list of ROM banks +; +; The pointer returned should point to a list of entries of SRomBank structures, +; usually declared with the ROM_BANK macro. +; The list is terminated by a zero size entry (four zero words) +; +; ROM_BANK PB, SIZE, LB, W, T, RS, SS +; PB = physical base address of bank +; SIZE = size of bank +; LB = linear base if override required - usually set this to 0 +; W = bus width (ROM_WIDTH_8, ROM_WIDTH_16, ROM_WIDTH_32) +; T = type (see TRomType enum in kernboot.h) +; RS = random speed +; SS = sequential speed +; +; Only PB, SIZE, LB are used by the rest of the bootstrap. +; The information given here can be modified by the SetupRomBank call, if +; dynamic detection and sizing of ROMs is required. +; +; Enter with : +; R10 points to super page +; R12 points to ROM header +; R13 points to valid stack +; +; Leave with : +; R0 = pointer +; Nothing else modified +;******************************************************************************* +GetRomBanks ROUT + ADR r0, %FT1 + MOV pc, lr +1 + IF CFG_MMDirect + ROM_BANK KRamTargetAddr, 0x08000000, 0, ROM_WIDTH_32, ERomTypeXIPFlash, 0, 0 ; image in RAM + ENDIF +; ROM_BANK PrimaryRomBase, PrimaryRomSize, 0, ROM_WIDTH_32, ERomTypeXIPFlash, 0, 0 +; ROM_BANK ExtensionRomBase, ExtensionRomSize, 0, ROM_WIDTH_32, ERomTypeXIPFlash, 0, 0 + DCD 0,0,0,0 ; terminator + + + + + +;******************************************************************************* +; Get a pointer to the list of hardware banks +; +; The pointer returned should point to a list of hardware banks declared with +; the HW_MAPPING and/or HW_MAPPING_EXT macros. A zero word terminates the list. +; For the direct memory model, all hardware on the system should be mapped here +; and the mapping will set linear address = physical address. +; For the moving or multiple model, only the hardware required to boot the kernel +; and do debug tracing needs to be mapped here. The linear addresses used will +; start at KPrimaryIOBase and step up as required with the order of banks in +; the list being maintained in the linear addresses used. +; +; HW_MAPPING PB, SIZE, MULT +; This declares a block of I/O with physical base PB and address range SIZE +; blocks each of which has a size determined by MULT. The page size used for +; the mapping is determined by MULT. The linear address base of the mapping +; will be the next free linear address rounded up to the size specified by +; MULT. +; The permissions used for the mapping are the standard I/O permissions (BTP_Hw). +; +; HW_MAPPING_EXT PB, SIZE, MULT +; This declares a block of I/O with physical base PB and address range SIZE +; blocks each of which has a size determined by MULT. The page size used for +; the mapping is determined by MULT. The linear address base of the mapping +; will be the next free linear address rounded up to the size specified by +; MULT. +; The permissions used for the mapping are determined by a BTP_ENTRY macro +; immediately following this macro in the HW bank list or by a DCD directive +; specifying a different standard permission type. +; +; HW_MAPPING_EXT2 PB, SIZE, MULT, LIN +; This declares a block of I/O with physical base PB and address range SIZE +; blocks each of which has a size determined by MULT. The page size used for +; the mapping is determined by MULT. The linear address base of the mapping +; is specified by the LIN parameter. +; The permissions used for the mapping are the standard I/O permissions (BTP_Hw). +; +; HW_MAPPING_EXT3 PB, SIZE, MULT, LIN +; This declares a block of I/O with physical base PB and address range SIZE +; blocks each of which has a size determined by MULT. The page size used for +; the mapping is determined by MULT. The linear address base of the mapping +; is specified by the LIN parameter. +; The permissions used for the mapping are determined by a BTP_ENTRY macro +; immediately following this macro in the HW bank list or by a DCD directive +; specifying a different standard permission type. +; +; Configurations without an MMU need not implement this function. +; +; Enter with : +; R10 points to super page +; R12 points to ROM header +; R13 points to valid stack +; +; Leave with : +; R0 = pointer +; Nothing else modified +;******************************************************************************* +GetHwBanks ROUT + ADR r0, %FT1 + MOV pc, lr + +1 + IF CFG_MMDirect + HW_MAPPING KHwLANPhys ,1, HW_MULT_1M ; LAN, FPGA + HW_MAPPING 0x18000000 ,1, HW_MULT_1M ; I/O registers @ 18000000 + HW_MAPPING KHwBaseMPcorePrivatePhys,1, HW_MULT_1M ; MPCORE private range + ELSE + HW_MAPPING KHwUART0Phys ,1, HW_MULT_4K ; Mapped at KPrimaryIOBase + 0 + HW_MAPPING KHwBaseMPcorePrivatePhys,2, HW_MULT_4K ; Mapped at KPrimaryIOBase + 1000h + HW_MAPPING KHwTimer0Phys ,2, HW_MULT_4K ; Mapped at KPrimaryIOBase + 3000h + HW_MAPPING KHwDispPhys ,4, HW_MULT_4K ; Mapped at KPrimaryIOBase + 5000h + HW_MAPPING KHwI2CPhys ,2, HW_MULT_4K ; Mapped at KPrimaryIOBase + 9000h + HW_MAPPING KHwFPGAPhys ,1, HW_MULT_4K ; Mapped at KPrimaryIOBase + B000h + HW_MAPPING KHwSPDIFPhys ,1, HW_MULT_4K ; Mapped at KPrimaryIOBase + C000h + HW_MAPPING KHwSDPhys ,1, HW_MULT_4K ; Mapped at KPrimaryIOBase + D000h + HW_MAPPING KHwAHBEXDMACPhys ,6, HW_MULT_4K ; Mapped at KPrimaryIOBase + E000h + HW_MAPPING KHwLANPhys ,1, HW_MULT_4K ; Mapped at KPrimaryIOBase + 14000h + HW_MAPPING KHwGPIOPhys ,1, HW_MULT_4K ; Mapped at KPrimaryIOBase + 15000h + HW_MAPPING KHwAHB32PCI_ExtPhys ,2, HW_MULT_4K ; Mapped at KPrimaryIOBase + 16000h + HW_MAPPING KHwUSBHPhys ,2, HW_MULT_4K ; Mapped at KPrimaryIOBase + 18000h + HW_MAPPING KHwAXI64DMACPhys ,1, HW_MULT_4K ; Mapped at KPrimaryIOBase + 1A000h + ; Next to be mapped at KPrimaryIOBase + 1B000h + ENDIF + DCD 0 ; Terminator + +;******************************************************************************* +; Set up RAM bank +; +; Do any additional RAM controller initialisation for each RAM bank which wasn't +; done by InitialiseHardware. +; Called twice for each RAM bank :- +; First with R3 = 0xFFFFFFFF before bank has been probed +; Then, if RAM is present, with R3 indicating validity of each byte lane, ie +; R3 bit 0=1 if D0-7 are valid, bit1=1 if D8-15 are valid etc. +; For each call R1 specifies the bank physical base address. +; +; Enter with : +; R10 points to super page +; R12 points to ROM header +; R13 points to stack +; R1 = physical base address of bank +; R3 = width (bottom 4 bits indicate validity of byte lanes) +; 0xffffffff = preliminary initialise +; +; Leave with : +; No registers modified +;******************************************************************************* +SetupRamBank ROUT + MOV pc, lr + + + + + +;******************************************************************************* +; Set up ROM bank +; +; Do any required autodetection and autosizing of ROMs and any additional memory +; controller initialisation for each ROM bank which wasn't done by +; InitialiseHardware. +; +; The first time this function is called R11=0 and R0 points to the list of +; ROM banks returned by the BTF_RomBanks call. This allows any preliminary setup +; before autodetection begins. +; +; This function is subsequently called once for each ROM bank with R11 pointing +; to the current information held about that ROM bank (SRomBank structure). +; The structure pointed to by R11 should be updated with the size and width +; determined. The size should be set to zero if there is no ROM present in the +; bank. +; +; Enter with : +; R10 points to super page +; R12 points to ROM header +; R13 points to stack +; R11 points to SRomBank info for this bank +; R11 = 0 for preliminary initialise (all banks) +; +; Leave with : +; Update SRomBank info with detected size/width +; Set the size field to 0 if the ROM bank is absent +; Can modify R0-R4 but not other registers +; +;******************************************************************************* +SetupRomBank ROUT + MOV pc, lr + + + + + +;******************************************************************************* +; Reserve physical memory +; +; Reserve any physical RAM needed for platform-specific purposes before the +; bootstrap begins allocating RAM for page tables/kernel data etc. +; +; There are two methods for this: +; 1. The function ExciseRamArea may be used. This will remove a contiguous +; region of physical RAM from the RAM bank list. That region will never +; again be identified as RAM. +; 2. A list of excluded physical address ranges may be written at [R11]. +; This should be a list of (base,size) pairs terminated by a (0,0) entry. +; This RAM will still be identified as RAM by the kernel but will not +; be allocated by the bootstrap and will subsequently be marked as +; allocated by the kernel immediately after boot. +; +; Enter with : +; R10 points to super page +; R11 indicates where preallocated RAM list should be written. +; R12 points to ROM header +; R13 points to stack +; +; Leave with : +; R0-R3 may be modified. Other registers should be preserved. +;******************************************************************************* +ReservePhysicalMemory ROUT +; IF :DEF: CFG_AlternateEntryPoint +; IF 0 +; STMFD sp!, {r9,r11,lr} +; LDR r0, =KRamTargetAddr ; reserve the first 64MB RAM for the image to download into. +; MOV r1, #0x4000000 ; 64MB +; MOV r2, #0 +; MOV r11, #0 +; LDR r9, [r10, #SSuperPageBase_iRamBootData] +; BL ExciseRamArea ; remove RAM +; LDMFD sp!, {r9,r11,pc} +; ENDIF + MOV pc, lr + + IF CFG_MMDirect + INIT_NUMERIC_CONSTANT KTTBRExtraBits, 0x02 + ELSE + IF SMP + INIT_NUMERIC_CONSTANT KTTBRExtraBits, 0x02 + ELSE + INIT_NUMERIC_CONSTANT KTTBRExtraBits, 0x08 + ENDIF + ENDIF + + +;******************************************************************************* +; Return parameter specified by R0 (see TBootParam enum) +; +; Enter with : +; R0 = parameter number +; +; Leave with : +; If parameter value is supplied, R0 = value and N flag clear +; If parameter value is not supplied, N flag set. In this case the +; parameter may be defaulted or the system may fault. +; R0,R1,R2 modified. No other registers modified. +; +;******************************************************************************* +GetParameters ROUT + ADR r1, ParameterTable + B FindParameter +ParameterTable + ; Include any parameters specified in TBootParam enum here + ; if you want to override them. + DCD BPR_TTBRExtraBits, KTTBRExtraBits + IF CFG_MMDirect + DCD BPR_UncachedLin, 0x7F000000 ; parameter number, parameter value + IF SMP + DCD BPR_APBootLin, 0x7F001000 ; parameter number, parameter value + ENDIF +; IF CFG_BootLoader +; DCD BPR_BootLdrImgAddr, KRamImageAddr +; ENDIF + ENDIF + DCD -1 ; terminator + +;******************************************************************************* +; Do final platform-specific initialisation before booting the kernel +; +; Typical uses for this call would be: +; 1. Mapping cache flushing areas +; 2. Setting up pointers to routines in the bootstrap which are used by +; the variant or drivers (eg idle code). +; +; Enter with : +; R10 points to super page +; R11 points to TRomImageHeader for the kernel +; R12 points to ROM header +; R13 points to stack +; +; Leave with : +; R0-R9 may be modified. Other registers should be preserved. +; +;******************************************************************************* +FinalInitialise ROUT + STMFD sp!, {lr} + + IF SMP +; Handshake with APs + + IF CFG_MMDirect + LDR r7, =KHwBaseMPcorePrivatePhys ; R7 points to SCU (physical address for direct memory model) + ELSE + LDR r7, =KPrimaryIOBase + 0x1000 ; R7 points to SCU (virtual address for other memory models) + ENDIF + ADD r8, r7, #0x1000 ; Virtual address of GIC Distributor + ADD r9, r7, #0x100 ; Virtual address of GIC CPU Interface + LDR r5, [r7, #4] ; SCU configuration register + DWORD r5, "SCU Config" + AND r5, r5, #3 + ADD r5, r5, #1 ; r5 = number of CPUs + DWORD r5, "NCPUs" + MOV r6, #0 ; CPU number + B %FA2 +1 + DWORD r6, "CPU" + BL HandshakeAP ; handshake with this AP +2 + ; Turn on LED for this CPU (CPU0==LED0, etc...) + GET_ADDRESS r0, KHwFpgaLedsPhyicalBase, KHwFpgaLedsLinBase + ; r0 is the address of the 16 bit LED register in FPGA, aka FLED + LDRH r1, [r0] ; read the contents of FLED into r1 + MOV r2, #KHtFpgaLed0 + MOV r2, r2, LSL r6 ; r2 is the LED value we want to OR in (ie, 1<threshold -> 2Gb per process, size<=threshold -> 1Gb per process +; Defaults to 32Mb. +; INIT_NUMERIC_CONSTANT CFG_ARMV6_LARGE_CONFIG_THRESHOLD, + +; For the direct memory model only, include the following line if you wish the exception vectors at the +; start of the bootstrap to be used at all times. This is only relevant if an MMU is present - this option +; is mandatory if not. +; GBLL CFG_UseBootstrapVectors +; +; If the above option is in use (including if no MMU is present) the following symbol should be defined +; to specify the offset from the bootstrap to the kernel image. + INIT_NUMERIC_CONSTANT KernelCodeOffset, 0x4000 + +; Include the following line if you wish to include the ROM autodetection code based on data bus +; capacitance and image repeats. +; GBLL CFG_AutoDetectROM + +; Include the following line to minimise the initial kernel heap size +; On the direct memory model the size of the kernel data area (super page to end of kernel heap) +; is rounded up to the next 1Mb if this is not included, 4K if it is. +; On the moving and multiple models, the size of the initial kernel heap area is rounded up to +; the next 64K if this is not included, 4K if it is. +; GBLL CFG_MinimiseKernelHeap + +; On the moving or multiple memory models, include either or both of the following lines to +; specify the size of the initial kernel heap +; INIT_NUMERIC_CONSTANT CFG_KernelHeapMultiplier, +; INIT_NUMERIC_CONSTANT CFG_KernelHeapBaseSize, +; +; The initial kernel heap size is MAX( + * N / 16, value specified in ROMBUILD ) +; where N is the total physical RAM size in pages. +; defaults to 24K and defaults to 9*16 (ie 9 bytes per page). + +; Uncomment if using ARM1136 processor and ARM1136 Erratum 353494 +; "Rare conditions can cause corruption of the Instruction Cache" +; is fixed on this hardware. +; +; NOTE: The boot table should use this macro to determine whether RONO or RORO permissions +; are used for the exception vectors. If the erratum is not fixed, RORO must be used. +; +; GBLL CFG_CPU_ARM1136_ERRATUM_353494_FIXED + +; Uncomment if using ARM1136 processor and ARM1136 Erratum 364296 +; "Possible Cache Data Corruption with Hit-Under-Miss" +; is fixed on this hardware. +; +; GBLL CFG_CPU_ARM1136_ERRATUM_364296_FIXED + +; Uncomment if using ARM1136 processor and ARM1136 Erratum 399234 +; "Write back data cache entry evicted by write through entry causes data corruption" +; is fixed on this hardware. +; Workaround +; The erratum may be avoided by marking all cacheable memory as one of write through or write back. +; This requires the memory attributes described in the translation tables to be modified by software +; appropriately, or the use of the remapping capability to remap write through regions to non cacheable. +; +; If this macro is enabled, it should be accompanied by: +; "#define __CPU_ARM1136_ERRATUM_399234_FIXED" in variant.mmh +; GBLL CFG_CPU_ARM1136_ERRATUM_399234_FIXED + + +; Uncomment if: +; 1) using ARM1136 processor and ARM1136 Erratum 411920: "Invalidate Entire Instruction Cache +; operation might fail to invalidate some lines if coincident with linefill" +; is fixed on this hardware, or +; 2) using ARM1176 processor and ARM1176 Erratum 415045: "Invalidate Entire Instruction Cache +; operation might fail to invalidate some lines if coincident with linefill +; is fixed on this hardware. +; Workaround: +; 1) Disables the use of of prefetch range cache operations by setting RV bit in Auxiliary Ctrl Reg. +; 2) Replaces Invalidate ICache operation with the sequence defined in the errata document. +; If this macro is enabled, it should be accompanied by: +; "#define __CPU_ARM1136_ERRATUM_411920_FIXED" in variant.mmh +; +; GBLL CFG_CPU_ARM1136_ERRATUM_411920_FIXED + + +; Uncomment if using ARM1136 processor and ARM1136 Erratum 415662: "Invalidate Instruction Cache by +; Index might corrupt cache when used with background prefetch range" is fixed on this hardware. +; Workaround: +; Disables the use of of prefetch range cache operations by setting RV bit in Auxiliary Ctrl Reg. +; +; GBLL CFG_CPU_ARM1136_ERRATUM_415662_FIXED + + +; Uncomment if this variant config needs to support the Shadow Memory Regions +; (SMR) feature in the kernel. Basically allows media based images to be copied +; into memory which is later reserved by the Kernel RAM Allocator. +; One user of the SMR feature is the HCR component when used with media based +; setting repository. Thus variant configs that support the new MHA HCR +; component and expect media based settings must define this macro e.g. NAND +; Core Image ROM, but not BootLoader ROM etc. +; + GBLL CFG_ENABLE_SMR_SUPPORT + + +; These are deduced from the supplied configuration +; CFG_ARMV6 +; CFG_MMUPresent +; CFG_CachePresent +; CFG_WriteBufferPresent +; CFG_SplitCache +; CFG_SplitTLB +; CFG_AltDCachePresent +; CFG_WriteBackCache +; CFG_CacheWriteAllocate +; CFG_CachePhysicalTag +; CFG_CacheFlushByDataRead +; CFG_CacheFlushByWaySetIndex +; CFG_CacheFlushByLineAlloc +; CFG_CachePolicyInPTE +; CFG_TEX +; CFG_SingleEntryDCacheFlush +; CFG_SingleEntryICacheFlush +; CFG_SingleEntryITLBFlush +; CFG_SingleEntryTLBFlush +; CFG_CacheTypeReg +; CFG_BTBPresent +; CFG_CARPresent +; CFG_PrefetchBuffer +; CFG_FCSE_Present +; CFG_ASID_Present +; CFG_IncludeRAMAllocator + + IF :DEF: CFG_MMFlexible + GBLL CFG_SupportEmulatedRomPaging + ENDIF + + END diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/csi.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/csi.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "csi_config.mmh" + +// PIL source +#include "../../../../os/kernelhwsrv/kernel/eka/drivers/iic/iic_channel.mmh" +sourcepath ../../../../os/kernelhwsrv/kernel/eka/drivers/iic +source IIC_PIL_SOURCE + + + +// PSL source +sourcepath ../naviengine_assp/csi +source csi_psl.cpp + +#ifdef __USE_MASTER_MODE__ +macro MASTER_MODE +macro CPU_AFFINITY_ANY +source csi_master.cpp +#endif + +// PSL source: Slave +#ifdef __USE_SLAVE_MODE__ +macro SLAVE_MODE +source csi_slave.cpp +#endif + +// define bus type +macro BUS_IMPLMENTATION_PRIORITY=(KExtensionMaximumPriority-2) + +target VariantTarget(csi,dll) +targettype kext + +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_NE1_TB_SYSTEMINCLUDE(specific) + +library VariantTarget(gpio,lib) +library hcr.lib + + +//VENDORID 0x70000001 + +//uid 0x100039d0 0x10285812 +//capability all + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/csi_config.mmh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/csi_config.mmh Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +// csi_config.mmh + +// Select the mode to build +// For Master-Slave mode, uncomment both MASTER and SLAVE defines +#define __USE_MASTER_MODE__ +#define __USE_SLAVE_MODE__ diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/csi_ctrless.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/csi_ctrless.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,88 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "csi_config.mmh" + +// Select the mode to build +// For Master-Slave mode, uncomment both MASTER and SLAVE defines + +macro STANDALONE_CHANNEL +#define STANDALONE_CHANNEL /*Only for iic_channel.mmh to pick up the needed source files*/ + +// PIL source +#include "../../../../os/kernelhwsrv/kernel/eka/drivers/iic/iic_channel.mmh" +sourcepath ../../../../os/kernelhwsrv/kernel/eka/drivers/iic +source IIC_PIL_SOURCE + + + +// PSL source +sourcepath ../naviengine_assp/csi +source csi_psl.cpp + +#ifdef __USE_MASTER_MODE__ +macro MASTER_MODE +//macro CPU_AFFINITY_ANY +source csi_master.cpp +#endif + +// PSL source: Slave +#ifdef __USE_SLAVE_MODE__ +macro SLAVE_MODE +source csi_slave.cpp +#endif + +// define bus type +macro BUS_IMPLMENTATION_PRIORITY=(KExtensionMaximumPriority-2) + +target VariantTarget(csi_ctrless,dll) +targettype kext + +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +// If a client doesn't specify any mode, the build is still supported +// However, if you run t_csi, you will get both master and slave test +// not supported with a returned KErrNotSupported. +#if defined (__USE_MASTER_MODE__) && defined(__USE_SLAVE_MODE__) +deffile ~/csi_ctrless.def +#elif defined (__USE_MASTER_MODE__) +deffile ~/csi_ctrless_masteronly.def +#elif defined (__USE_SLAVE_MODE__) +deffile ~/csi_ctrless_slaveonly.def +#else +deffile ~/csi_ctrless_nomode.def +#endif + +library VariantTarget(gpio,lib) +library hcr.lib + + +//VENDORID 0x70000001 + +//uid 0x100039d0 0x10285812 +//capability all + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/eabi/csi_ctrless_masteronlyu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/eabi/csi_ctrless_masteronlyu.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,14 @@ +EXPORTS + _ZN17DCsiChannelMaster3NewEiN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 1 NONAME + _ZN20TIicBusSlaveCallback7DfcFuncEPv @ 2 NONAME + _ZN25DIicBusChannelMasterSlaveC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP20DIicBusChannelMasterP19DIicBusChannelSlave @ 3 NONAME + _ZN25DIicBusChannelMasterSlaveC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP20DIicBusChannelMasterP19DIicBusChannelSlave @ 4 NONAME + _ZTI17DCsiChannelMaster @ 5 NONAME + _ZTI19DIicBusChannelSlave @ 6 NONAME + _ZTI20DIicBusChannelMaster @ 7 NONAME + _ZTI25DIicBusChannelMasterSlave @ 8 NONAME + _ZTV17DCsiChannelMaster @ 9 NONAME + _ZTV19DIicBusChannelSlave @ 10 NONAME + _ZTV20DIicBusChannelMaster @ 11 NONAME + _ZTV25DIicBusChannelMasterSlave @ 12 NONAME + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/eabi/csi_ctrless_nomodeu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/eabi/csi_ctrless_nomodeu.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,11 @@ +EXPORTS + _ZN20TIicBusSlaveCallback7DfcFuncEPv @ 1 NONAME + _ZN25DIicBusChannelMasterSlaveC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP20DIicBusChannelMasterP19DIicBusChannelSlave @ 2 NONAME + _ZN25DIicBusChannelMasterSlaveC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP20DIicBusChannelMasterP19DIicBusChannelSlave @ 3 NONAME + _ZTI19DIicBusChannelSlave @ 4 NONAME + _ZTI20DIicBusChannelMaster @ 5 NONAME + _ZTI25DIicBusChannelMasterSlave @ 6 NONAME + _ZTV19DIicBusChannelSlave @ 7 NONAME + _ZTV20DIicBusChannelMaster @ 8 NONAME + _ZTV25DIicBusChannelMasterSlave @ 9 NONAME + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/eabi/csi_ctrless_slaveonlyu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/eabi/csi_ctrless_slaveonlyu.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,14 @@ +EXPORTS + _ZN16DCsiChannelSlave3NewEiN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 1 NONAME + _ZN20TIicBusSlaveCallback7DfcFuncEPv @ 2 NONAME + _ZN25DIicBusChannelMasterSlaveC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP20DIicBusChannelMasterP19DIicBusChannelSlave @ 3 NONAME + _ZN25DIicBusChannelMasterSlaveC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP20DIicBusChannelMasterP19DIicBusChannelSlave @ 4 NONAME + _ZTI16DCsiChannelSlave @ 5 NONAME + _ZTI19DIicBusChannelSlave @ 6 NONAME + _ZTI20DIicBusChannelMaster @ 7 NONAME + _ZTI25DIicBusChannelMasterSlave @ 8 NONAME + _ZTV16DCsiChannelSlave @ 9 NONAME + _ZTV19DIicBusChannelSlave @ 10 NONAME + _ZTV20DIicBusChannelMaster @ 11 NONAME + _ZTV25DIicBusChannelMasterSlave @ 12 NONAME + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/eabi/csi_ctrlessu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/eabi/csi_ctrlessu.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,17 @@ +EXPORTS + _ZN16DCsiChannelSlave3NewEiN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 1 NONAME + _ZN17DCsiChannelMaster3NewEiN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 2 NONAME + _ZN20TIicBusSlaveCallback7DfcFuncEPv @ 3 NONAME + _ZTI16DCsiChannelSlave @ 4 NONAME + _ZTI17DCsiChannelMaster @ 5 NONAME + _ZTI19DIicBusChannelSlave @ 6 NONAME + _ZTI20DIicBusChannelMaster @ 7 NONAME + _ZTI25DIicBusChannelMasterSlave @ 8 NONAME + _ZTV16DCsiChannelSlave @ 9 NONAME + _ZTV17DCsiChannelMaster @ 10 NONAME + _ZTV19DIicBusChannelSlave @ 11 NONAME + _ZTV20DIicBusChannelMaster @ 12 NONAME + _ZTV25DIicBusChannelMasterSlave @ 13 NONAME + _ZN25DIicBusChannelMasterSlaveC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP20DIicBusChannelMasterP19DIicBusChannelSlave @ 14 NONAME + _ZN25DIicBusChannelMasterSlaveC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP20DIicBusChannelMasterP19DIicBusChannelSlave @ 15 NONAME + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/eabi/gpio.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/eabi/gpio.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,31 @@ +EXPORTS + _ZN4GPIO10GetPinBiasEiRNS_9TGpioBiasE @ 1 NONAME + _ZN4GPIO10GetPinModeEiRNS_9TGpioModeE @ 2 NONAME + _ZN4GPIO10SetPinBiasEiNS_9TGpioBiasE @ 3 NONAME + _ZN4GPIO10SetPinModeEiNS_9TGpioModeE @ 4 NONAME + _ZN4GPIO12EnableWakeupEi @ 5 NONAME + _ZN4GPIO13BindInterruptEiPFvPvES0_ @ 6 NONAME + _ZN4GPIO13DisableWakeupEi @ 7 NONAME + _ZN4GPIO13GetInputStateEiP13TGpioCallback @ 8 NONAME + _ZN4GPIO13GetInputStateEiRNS_10TGpioStateE @ 9 NONAME + _ZN4GPIO14ClearInterruptEi @ 10 NONAME + _ZN4GPIO14GetOutputStateEiRNS_10TGpioStateE @ 11 NONAME + _ZN4GPIO14SetOutputStateEiNS_10TGpioStateE @ 12 NONAME + _ZN4GPIO14SetOutputStateEiNS_10TGpioStateEP13TGpioCallback @ 13 NONAME + _ZN4GPIO15EnableInterruptEi @ 14 NONAME + _ZN4GPIO15GetDebounceTimeEiRi @ 15 NONAME + _ZN4GPIO15GetPinDirectionEiRNS_14TGpioDirectionE @ 16 NONAME + _ZN4GPIO15IsWakeupEnabledEiRi @ 17 NONAME + _ZN4GPIO15SetDebounceTimeEii @ 18 NONAME + _ZN4GPIO15SetPinDirectionEiNS_14TGpioDirectionE @ 19 NONAME + _ZN4GPIO15StaticExtensionEiiPvS0_ @ 20 NONAME + _ZN4GPIO15UnbindInterruptEi @ 21 NONAME + _ZN4GPIO16DisableInterruptEi @ 22 NONAME + _ZN4GPIO16SetWakeupTriggerEiNS_21TGpioDetectionTriggerE @ 23 NONAME + _ZN4GPIO18IsInterruptEnabledEiRi @ 24 NONAME + _ZN4GPIO19SetInterruptTriggerEiNS_21TGpioDetectionTriggerE @ 25 NONAME + _ZN4GPIO20GetRawInterruptStateEiRi @ 26 NONAME + _ZN4GPIO23GetMaskedInterruptStateEiRi @ 27 NONAME + _ZN4GPIO31GetPinIdleConfigurationAndStateEiRi @ 28 NONAME + _ZN4GPIO31SetPinIdleConfigurationAndStateEii @ 29 NONAME + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/eabi/lcdgcene1_tbu.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/eabi/lcdgcene1_tbu.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,9 @@ +EXPORTS + _Z20CreatePhysicalDevicev @ 1 NONAME + _ZN16DLcdPowerHandler16RegisterCallbackEP16TLcdUserCallBack @ 2 NONAME + _ZN16DLcdPowerHandler18DeRegisterCallbackEP16TLcdUserCallBack @ 3 NONAME + _ZTI18DDisplayPddFactory @ 4 NONAME + _ZTI18DDisplayPddNaviEng @ 5 NONAME + _ZTV18DDisplayPddFactory @ 6 NONAME + _ZTV18DDisplayPddNaviEng @ 7 NONAME + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/eabi/power.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/eabi/power.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,7 @@ +EXPORTS + _ZN22TNE1_TBPowerController11WakeupEventEv @ 1 NONAME + _ZN22TNE1_TBPowerController15ResourceManagerEv @ 2 NONAME ABSENT + _ZN22TNE1_TBPowerController10EngageCoreEiR15TRetireEngageCb @ 3 NONAME ABSENT + _ZN22TNE1_TBPowerController10RetireCoreEiR15TRetireEngageCb @ 4 NONAME ABSENT + _ZN22TNE1_TBPowerController9IdleCountEv @ 5 NONAME + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/eabi/variant.def --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/eabi/variant.def Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,9 @@ +EXPORTS + VariantInitialise @ 1 NONAME + _ZN7Variant10PowerResetEv @ 2 NONAME + _ZN7Variant14BaseLinAddressEv @ 3 NONAME + _ZN7Variant16MarkDebugPortOffEv @ 4 NONAME + _ZN7Variant8SwitchesEv @ 5 NONAME + _ZN13NE1_TBVariant15GetSerialNumberEv @ 6 NONAME + _ZN13NE1_TBVariant15SetSerialNumberEm @ 7 NONAME + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/enet.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/enet.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/ethernet.mmp +* +*/ + + + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(ethernet,pdd) +targettype pdd +romtarget ethernet.pdd + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) +SYMBIAN_NE1_TB_SYSTEMINCLUDE(specific) +USERINCLUDE inc + +sourcepath ethernet +source shared_ethernet.cpp +source smcs9118_ethernet.cpp + +library VariantTarget(kanaviengine,lib) +library VariantTarget(ecust,lib) +library VariantTarget(gpio,lib) + +epocallowdlldata + +uid 0x100039d0 0x1000015c +vendorid 0x70000001 + +capability all +MACRO CPU_AFFINITY_ANY +SMPSAFE + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/estart.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/estart.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* hwip_nec_naviengine/ne1_tb/estart.mmp +* estart.exe Base Symbian OS startup process +* +*/ + + + +/** + @file +*/ + +#include + +TARGET VariantTarget(e32strt,exe) +CAPABILITY TCB WriteDeviceData DiskAdmin ProtServ AllFiles PowerMgmt + +TARGETTYPE exe + + +SOURCEPATH ../../../../os/kernelhwsrv/userlibandfileserver/fileserver/estart +SOURCE estart.cpp +SOURCEPATH estart +SOURCE estartmain.cpp + +STRICTDEPEND + +USERINCLUDE ../../../../os/kernelhwsrv/userlibandfileserver/fileserver/estart +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +LIBRARY efsrv.lib euser.lib hal.lib +LIBRARY domaincli.lib + +UID 0 0x10272C04 +VENDORID 0x70000001 + + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/estart/estart.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/estart/estart.txt Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* estart.mmp +* +*/ + +C: 0 ELOCAL FAT 0 FS_FORMAT_COLD,FS_SYNC_DRIVE # IRAM +D: 1 ELOCAL FAT 0 FS_SCANDRIVE # MMC + + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/estart/estartmain.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/estart/estartmain.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* estart.mmp +* +*/ + + + +#include +#include +#include "estart.h" + +class TNaviEngineFSStartup : public TFSStartup + { +public: + virtual TPtrC LocalDriveMappingFileName(); + }; + + +_LIT(KLocalDriveMappingFile,"Z:\\SYS\\DATA\\ESTART.TXT"); + +/** Return the filename of the drive mapping file. +@return A non-modifiable ptr descriptor containing the path and filename of the mapping file. +*/ +TPtrC TNaviEngineFSStartup::LocalDriveMappingFileName() + { + + DEBUGPRINT("LocalDriveMappingFileName"); + + InitCompositeFileSystem(); + + return(KLocalDriveMappingFile()); + } + +GLDEF_C TInt E32Main() + { + + TNaviEngineFSStartup fsStart; + fsStart.Init(); + + fsStart.Run(); + + fsStart.StartSystem(); + + fsStart.Close(); + return(0); + } + + + + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/estart/estarttechview.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/estart/estarttechview.txt Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* estart.mmp +* +*/ + +C: 0 ELOCAL FAT 0 FS_FORMAT_COLD,FS_SYNC_DRIVE # IRAM +E: 1 ELOCAL FAT 0 FS_SCANDRIVE # MMC diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/ethernet/shared_ethernet.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/ethernet/shared_ethernet.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,255 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\ethernet\shared_ethernet.cpp +* Ethernet driver implementation. +* +*/ + + + +/** + @addtogroup + @ingroup +*/ + +#include "shared_ethernet.h" + + +/********************************************************************/ +/* Class DEthernetPowerHandler implementation */ +/********************************************************************/ + +/* + * Device power down modes + */ +enum TPowerDownMode + { + ENormalPowerDown, + EEmergencyPowerDown + }; + +_LIT(KLitEthernet,"Ethernet"); + +DEthernetPowerHandler::DEthernetPowerHandler() +:DPowerHandler(KLitEthernet), +iCurPoweredUp(EFalse), +iCurPowerState(EPwActive) + { + } + +void DEthernetPowerHandler::RequestPower() + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetPowerHandler::RequestPower()"); + #endif + + // Do power up the Ethernet if not already powered up. + if(!iCurPoweredUp) + { + iCurPoweredUp = ETrue; + } + } + +TInt DEthernetPowerHandler::SetEthernetPdd(DEthernetPdd* aEthernetPdd) + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetPowerHandler::SetEthernetPdd()"); + #endif + + iEthernetPdd = aEthernetPdd; + return KErrNone; + } + +void DEthernetPowerHandler::PowerUp() + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetPowerHandler::PowerUp()"); + #endif + iCurPowerState = EPwActive; + iEthernetPdd->Wakeup(); + PowerUpDone(); + } + +void DEthernetPowerHandler::PowerDown(TPowerState aState) + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetPowerHandler::PowerDown()"); + #endif + iCurPowerState = aState; + // Stop recieving more frames. + iEthernetPdd->Stop(EStopNormal); + + // Do power down on Ethernet + RelinquishPower(); + PowerDownDone(); + } + +void DEthernetPowerHandler::RelinquishPower() + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetPowerHandler::RelinquishPower()"); + #endif + + // Do power standby on Ethernet if it is powered up. + if(iCurPoweredUp) + { + iCurPoweredUp = EFalse; + } + iEthernetPdd->Sleep(); + } + +DEthernetPdd::DEthernetPdd() +//Constructor + { + } + +DEthernetPdd::~DEthernetPdd() +//Destructor + { + } + +TInt DEthernetPdd::Start() +/** + * Start receiving frames + * @return KErrNone if driver started + */ + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetPdd::Start()"); + #endif + + if(iReady) + { + return KErrNone; + } + iReady = ETrue; + TInt r = Configure(iDefaultConfig); + return r; + } + +TInt DEthernetPdd::ValidateConfig(const TEthernetConfigV01& aConfig) const +/** + * Validate a new config + * Validates a new configuration should be called before Configure + * @param aConfig is the configuration to be validated + * @return ETrue or EFalse if the Configuration is allowed + * @see Configure() + */ + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetPdd::ValidateConfig()"); + #endif + switch(aConfig.iEthSpeed) + { + case KEthSpeedAuto: + case KEthSpeed10BaseT: + case KEthSpeed100BaseTX: + break; + case KEthSpeedUnknown: + default: + return KErrNotSupported; + } + + switch(aConfig.iEthDuplex) + { + case KEthDuplexAuto: + case KEthDuplexFull: + case KEthDuplexHalf: + break; + default: + case KEthDuplexUnknown: + return KErrNotSupported; + } + + return KErrNone; + } + + + +void DEthernetPdd::GetConfig(TEthernetConfigV01& aConfig) const +/** + * Get the current config from the chip + * This returns the current configuration of the chip with the folling fields + * The Transmit Speed + * The Duplex Setting + * The MAC address + * @param aConfig is a TEthernetConfigV01 reference that will be filled in + */ + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetPdd::GetConfig()"); + #endif + aConfig = iDefaultConfig; + return; + } + + +void DEthernetPdd::CheckConfig(TEthernetConfigV01& /*aConfig*/) +/** + * Check a configuration + * @param aConfig a reference to the structure TEthernetConfigV01 with configuration to check + */ + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetPdd::CheckConfig()"); + #endif + return; + } + + +void DEthernetPdd::Caps(TDes8& /*aCaps*/) const +/** + * Query the device's capabilities + * @param aCaps To be filled in with the capabilites + */ + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetPdd::Caps()"); + #endif + return; + } + +TInt DEthernetPdd::DisableIrqs() +/** + * Disables all IRQ's + * @return The IRQ level before it was changed + * @see RestoreIrqs() + */ + { + return KErrNotSupported; + } + +void DEthernetPdd::RestoreIrqs(TInt /*aIrq*/) +/** + * Restore the IRQ's to the supplied level + * @param aIrq The level to set the irqs to. + * @see DisableIrqs() + */ + { + } + +TDfcQue* DEthernetPdd::DfcQ(TInt /*aUnit*/) +/** + * Return the DFC Queue that this device should use + * @param aUnit The Channel number + * @return Then DFC Queue to use + */ + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetPdd::DfcQ()"); + #endif + + return iDfcQ; + } diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/ethernet/shared_ethernet.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/ethernet/shared_ethernet.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,197 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\ethernet\shared_ethernet.h +* Ethernet driver common header +* +*/ + + + + +#ifndef __SHARED_ETHERNET_H__ +#define __SHARED_ETHERNET_H__ + +#include +#include +#include +#include +#include + +// +// Driver Constants +// + +class DEthernetPdd; + +/******Ethernet POWER HANDLER CLASS*****/ +class DEthernetPowerHandler : public DPowerHandler + { +public: + DEthernetPowerHandler(); + TInt SetEthernetPdd(DEthernetPdd* aEthernetPdd); + void PowerDown(TPowerState aState); + void PowerUp(); + void RequestPower(); + void RelinquishPower(); +private: + TBool iCurPoweredUp; + TPowerState iCurPowerState; + DEthernetPdd* iEthernetPdd; + }; + + +class DEthernetPdd : public DEthernet +/** +Ethernet PDD class. +*/ + { +public: + DEthernetPdd(); + ~DEthernetPdd(); + + /** + * Start receiving frames + * @return KErrNone if driver started + */ + virtual TInt Start() ; + /** + * Stop receiving frames + * @param aMode The stop mode + */ + virtual void Stop(TStopMode aMode) = 0; + + /** + * Validate a new config + * Validates a new configuration should be called before Configure + * @param aConfig is the configuration to be validated + * @return ETrue or EFalse if the Configuration is allowed + * @see Configure() + */ + virtual TInt ValidateConfig(const TEthernetConfigV01 &aConfig) const; + /** + * Configure the device + * Reconfigure the device using the new configuration supplied. + * This should not change the MAC address. + * @param aConfig The new configuration + * @see ValidateConfig() + * @see MacConfigure() + */ + virtual TInt Configure(TEthernetConfigV01 &aConfig) = 0; + /** + * Change the MAC address + * Attempt to change the MAC address of the device + * @param aConfig A Configuration containing the new MAC + * @see Configure() + */ + virtual void MacConfigure(TEthernetConfigV01 &aConfig) = 0; + /** + * Get the current config from the chip + * This returns the current configuration of the chip with the following fields + * The Transmit Speed + * The Duplex Setting + * The MAC address + * @param aConfig is a TEthernetConfigV01 reference that will be filled in + */ + virtual void GetConfig(TEthernetConfigV01 &aConfig) const; + /** + * Check a configuration + * @param aConfig a reference to the structure TEthernetConfigV01 with configuration to check + */ + virtual void CheckConfig(TEthernetConfigV01& aConfig); + + /** + * Query the device's capabilities + * @param aCaps To be filled in with the capabilites + */ + virtual void Caps(TDes8 &aCaps) const; + + /** + * Transmit data + * @param aBuffer reference to the data to be sent + * @return KErrNone if the data has been sent + */ + virtual TInt Send(TBuf8 &aBuffer) = 0; + /** + * Retrieve data from the device + * Pull the received data out of the device and into the supplied buffer. + * Need to be told if the buffer is OK to use as if it not we could dump + * the waiting frame in order to clear the interrupt if necessory. + * @param aBuffer Reference to the buffer to be used to store the data in + * @param okToUse Bool to indicate if the buffer is usable + * @return KErrNone if the buffer has been filled. + */ + virtual TInt ReceiveFrame(TBuf8 &aBuffer, + TBool okToUse) = 0; + + /** + * Disables all IRQ's + * @return The IRQ level before it was changed + * @see RestoreIrqs() + */ + virtual TInt DisableIrqs(); + /** + * Restore the IRQ's to the supplied level + * @param aIrq The level to set the irqs to. + * @see DisableIrqs() + */ + virtual void RestoreIrqs(TInt aIrq); + + /** + * Return the DFC Queue that this device should use + * @param aUnit The Channel number + * @return Then DFC Queue to use + */ + virtual TDfcQue* DfcQ(TInt aUnit); + + virtual TInt DoCreate() = 0; + + /** + * Put the card to sleep + */ + + virtual void Sleep() = 0; + /** + * Wake the card up + */ + virtual TInt Wakeup() = 0; + +protected: + static void ServiceRxDfc(TAny *aPtr); + + /** + * Does the soft reset of the lan card + */ + TInt CardSoftReset(); + +protected: + /** + * Contains the default/current configuration of the chip + */ + TEthernetConfigV01 iDefaultConfig; + /** + * Is ETrue if the chip has been fully configured. + */ + TBool iReady; + /** + * Is ETrue if the pdd has been created + */ + TBool iCreated; + DEthernetPowerHandler iPowerHandler; + TDynamicDfcQue* iDfcQ; + TInt32 iInterruptId; + }; + + +#endif //__SHARED_ETHERNET_H__ diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/ethernet/smcs9118_ethernet.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/ethernet/smcs9118_ethernet.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,1141 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\ethernet\shared_ethernet.h +* SMCS 9118 Ethernet driver implementation. +* +*/ + + + +#include "variant.h" +#include "smcs9118_ethernet.h" + +const TUint32 ONE_MSEC = 1000; // in nanoseconds +const TUint32 TWO_SECONDS = 2000; // in milliseconds +const TUint32 SMCS9118_MAC_TIMEOUT = 50; +const TUint32 SMCS9118_MAX_RETRIES = 100; + + +DEthernetPddFactory::DEthernetPddFactory() + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetPddFactory::DEthernetPddFactory()"); + #endif + iVersion=TVersion(KEthernetMajorVersionNumber, + KEthernetMinorVersionNumber, + KEthernetBuildVersionNumber); + } + +TInt DEthernetPddFactory::Install() + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetPddFactory::Install()"); + #endif + return SetName(&KEthernetPddName); + } + +void DEthernetPddFactory::GetCaps(TDes8& /*aDes*/) const +/* + * Return the drivers capabilities. + */ + { + } + + +TInt DEthernetPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer) +/* + * Create a Driver for the device. + */ + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetPddFactory::Create()"); + #endif + TInt r = Validate(aUnit, aInfo, aVer); + if (r != KErrNone) + { + return r; + } + DEthernetPdd* pP = new DEthernetSMCS9118Pdd; + aChannel = pP; + if (!pP) + { + return KErrNoMemory; + } + r = pP->DoCreate(); + return r; + } + +TInt DEthernetPddFactory::Validate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer) +/* + * Validate the requested configuration + */ + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetPddFactory::Validate()"); + #endif + + if (!Kern::QueryVersionSupported(iVersion,aVer)) + { + return KErrNotSupported; + } + + return KErrNone; + } + +#ifdef __SMP__ +TSpinLock DEthernetSMCS9118PddLock(SMCS9118_LOCK_ORDER); +#endif +DEthernetSMCS9118Pdd::DEthernetSMCS9118Pdd() +//Constructor + :iRxDfc(ServiceRxDfc, this, 1) + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetSMCS9118Pdd::DEthernetSMCS9118Pdd()"); + #endif + +#ifdef __SMP__ + iDriverLock = &DEthernetSMCS9118PddLock; +#endif + iReady = EFalse; + } + +DEthernetSMCS9118Pdd::~DEthernetSMCS9118Pdd() +//Destructor + { + + //cancel any pending DFC requests + iRxDfc.Cancel(); + + // UnRegister the power handler with Symbian Power Framework + iPowerHandler.RelinquishPower(); + iPowerHandler.Remove(); + + // UnRegister interrupts + DisableInterrupt(iInterruptId); + UnbindInterrupt(iInterruptId); + + if (iDfcQ) + iDfcQ->Destroy(); + } + +void DEthernetSMCS9118Pdd::Stop(TStopMode aMode) +/** + * Stop receiving frames + * @param aMode The stop mode + */ + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetSMCS9118Pdd::Stop()"); + #endif + + switch (aMode) + { + case EStopNormal: + case EStopEmergency: + iReady = EFalse; + iRxDfc.Cancel(); + // disable Rx, Tx + TUint32 status; + TInt32 err = ReadMac(SMCS9118_MAC_CR, status); + status &= ~(SMCS9118_MAC_RXEN | SMCS9118_MAC_TXEN | SMCS9118_MAC_RXALL); + err = WriteMac(SMCS9118_MAC_CR, status); + // clear any pending interrupts + Write32(SMCS9118_INT_EN, 0); + ByteTestDelay(1); + ClearInterrupt(iInterruptId); + // turn off the LED + status = Read32(SMCS9118_GPIO_CFG) & ~SMCS9118_GPIO_LED_EN; + Write32(SMCS9118_GPIO_CFG, status); + ByteTestDelay(1); + + break; + } + } + +TInt DEthernetSMCS9118Pdd::Configure(TEthernetConfigV01& /*aConfig*/) +/** + * Configure the device + * Reconfigure the device using the new configuration supplied. + * This should not change the MAC address. + * @param aConfig The new configuration + * @see ValidateConfig() + * @see MacConfigure() + * assume iDriverLock not held + */ + { + TUint32 retry; + TUint32 status; + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetSMCS9118Pdd::Configure()"); + #endif + + if ((status = CardSoftReset()) != (TUint32)KErrNone) + { + return status; + } + + TInt irq = DriverLock(); + // disable chip interrupts + Write32(SMCS9118_INT_EN, 0); + ByteTestDelay(1); + Write32(SMCS9118_INT_STS, 0xffffffff); + ByteTestDelay(2); + Write32(SMCS9118_FIFO_INT, 0); + ByteTestDelay(1); + Write32(SMCS9118_IRQ_CFG, SMCS9118_IRQ_CFG_DEAS|SMCS9118_IRQ_CFG_TYPE); + ByteTestDelay(3); + + // AutoFlowControl setup + Write32(SMCS9118_AFC_CFG, SMCS9118_AFC_CFG_VAL); + ByteTestDelay(1); + + // TX FIFO setup + status = Read32(SMCS9118_HW_CFG); + status |= SMCS9118_TX_FIFO_SZ; + Write32(SMCS9118_HW_CFG, status); + ByteTestDelay(1); + + // wait for EEPROM load + retry = SMCS9118_MAX_RETRIES; + do + { + status = Read32(SMCS9118_E2P_CMD); + if (!(status & SMCS9118_E2P_CMD_BUSY)) + { + break; + } + Kern::NanoWait(ONE_MSEC); + } while (--retry); + if (retry == 0) + { + DriverUnlock(irq); + return KErrGeneral; + } + + // GPIO setup - turn on the LED ! + Write32(SMCS9118_GPIO_CFG, SMCS9118_GPIO_GPIOBUF|SMCS9118_GPIO_LED_EN); + ByteTestDelay(1); + + // PHY reset + status = Read32(SMCS9118_PMT_CTRL); + status |= SMCS9118_PMT_PHY_RST; + Write32(SMCS9118_PMT_CTRL, status); + ByteTestDelay(7); + retry = SMCS9118_MAX_RETRIES; + do + { + status = Read32(SMCS9118_PMT_CTRL); + if (!(status & SMCS9118_PMT_PHY_RST)) + { + break; + } + Kern::NanoWait(ONE_MSEC); + } while (--retry); + if (retry == 0) + { + DriverUnlock(irq); + return KErrGeneral; + } + ByteTestDelay(1); + + // Auto negotiate setup + TInt32 err = ReadPhy(SMCS9118_PHY_AUTONEG_AD, status); + if (err != KErrNone) + { + DriverUnlock(irq); + return err; + } + status |= SMCS9118_PHY_DEF_ANEG; + err = WritePhy(SMCS9118_PHY_AUTONEG_AD, status); + if (err != KErrNone) + { + DriverUnlock(irq); + return err; + } + + err = ReadPhy(SMCS9118_PHY_AUTONEG_AD, status); + if (err != KErrNone) + { + DriverUnlock(irq); + return err; + } + + err = ReadPhy(SMCS9118_PHY_BCR, status); + if (err != KErrNone) + { + DriverUnlock(irq); + return err; + } + status |= (SMCS9118_PHY_ANEG_RESTART|SMCS9118_PHY_ANEG_EN); + err = WritePhy(SMCS9118_PHY_BCR, status); + if (err != KErrNone) + { + DriverUnlock(irq); + return err; + } + + // wait for auto negotiation + DriverUnlock(irq); + NKern::Sleep(TWO_SECONDS); + irq = DriverLock(); + + err = ReadPhy(SMCS9118_PHY_BSR, status); + if (err != KErrNone) + { + DriverUnlock(irq); + return err; + } + if (!(status & SMCS9118_PHY_ANEG_CMPL)) + { + DriverUnlock(irq); + return KErrGeneral; + } + + // update the config based on what we negotiated + if (status & (SMCS9118_PHY_100BTX|SMCS9118_PHY_100BTXFD)) + { + iDefaultConfig.iEthSpeed = KEthSpeed100BaseTX; + } + if (status & (SMCS9118_PHY_10BTFD|SMCS9118_PHY_100BTXFD)) + { + iDefaultConfig.iEthDuplex = KEthDuplexFull; + } + + // setup store + forward + status = Read32(SMCS9118_HW_CFG); + status |= SMCS9118_HW_CFG_SF; + Write32(SMCS9118_HW_CFG, status); + ByteTestDelay(1); + + // setup Tx and Rx + Write32(SMCS9118_TX_CFG, SMCS9118_TX_CFG_TXSAO|SMCS9118_TX_CFG_TX_ON); + ByteTestDelay(1); + + TInt r; + r = WriteMac(SMCS9118_MAC_CR, SMCS9118_MAC_RXEN|SMCS9118_MAC_TXEN|SMCS9118_MAC_RXALL); + if (r != KErrNone) + { + DriverUnlock(irq); + return r; + } + + // Enable interrupts to CPU + r = EnableInterrupt(iInterruptId); + if(r != KErrNone) + { + TInt err; + __KTRACE_OPT(KHARDWARE,Kern::Printf("DEthernetSMSC9118Pdd::Start --- Interrupt::Enable()=%d", r)); + + // Disable TX, RX and exit + status &= ~(SMCS9118_MAC_RXEN | SMCS9118_MAC_TXEN | SMCS9118_MAC_RXALL); + err = WriteMac(SMCS9118_MAC_CR, status); + if (err != KErrNone) + { + DriverUnlock(irq); + return err; + } + + DriverUnlock(irq); + return r; + } + + // Rx Interrupt + Write32(SMCS9118_INT_EN, SMCS9118_INT_EN_RSFL); + ByteTestDelay(1); + + DriverUnlock(irq); + return KErrNone; + } + + +void DEthernetSMCS9118Pdd::MacConfigure(TEthernetConfigV01& aConfig) +/** + * Change the MAC address + * Attempt to change the MAC address of the device + * @param aConfig A Configuration containing the new MAC + * @see Configure() + * assume iDriverLock not held + */ + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetSMCS9118Pdd::MacConfigure()"); + #endif + + + TUint32 mac, checkMac; + TInt err; + + TInt irq = DriverLock(); + mac = aConfig.iEthAddress[0]; + mac |= aConfig.iEthAddress[1]<<8; + mac |= aConfig.iEthAddress[2]<<16; + mac |= aConfig.iEthAddress[3]<<24; + + err = WriteMac(SMCS9118_MAC_ADDRL, mac); + if (err) + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("DEthernetSMCS9118Pdd::MacConfigure() -- Failed to set MAC Address")); + DriverUnlock(irq); + return; + } + err = ReadMac(SMCS9118_MAC_ADDRL, checkMac); + if (err || checkMac != mac) + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("DEthernetSMCS9118Pdd::MacConfigure() -- Failed to set MAC Address")); + DriverUnlock(irq); + return; + } + + mac = aConfig.iEthAddress[4]; + mac |= aConfig.iEthAddress[5]<<8; + err = WriteMac(SMCS9118_MAC_ADDRH, mac); + if (err) + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("DEthernetSMCS9118Pdd::MacConfigure() -- Failed to set MAC Address")); + DriverUnlock(irq); + return; + } + err = ReadMac(SMCS9118_MAC_ADDRH, checkMac); + if (err || checkMac != mac) + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("DEthernetSMCS9118Pdd::MacConfigure() -- Failed to set MAC Address")); + DriverUnlock(irq); + return; + } + + for (TInt i=0; i<=5; i++) + { + iDefaultConfig.iEthAddress[i] = aConfig.iEthAddress[i]; + } + + __KTRACE_OPT(KHARDWARE, Kern::Printf("-- MAC address %2x.%2x.%2x.%2x.%2x.%2x", + iDefaultConfig.iEthAddress[0], iDefaultConfig.iEthAddress[1], + iDefaultConfig.iEthAddress[2], iDefaultConfig.iEthAddress[3], + iDefaultConfig.iEthAddress[4], iDefaultConfig.iEthAddress[5])); + + DriverUnlock(irq); + return; + } + + +TInt DEthernetSMCS9118Pdd::Send(TBuf8& aBuffer) +/** + * Transmit data + * @param aBuffer reference to the data to be sent + * @return KErrNone if the data has been sent + * assume iDriverLock not held + */ + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetSMCS9118Pdd::Send()"); + #endif + + // Always request for power + iPowerHandler.RequestPower(); + TUint32* dataP = (TUint32 *)aBuffer.Ptr(); + TUint32 length = aBuffer.Length(); + + TInt irq = DriverLock(); + // can it fit + TUint32 status = Read32(SMCS9118_TX_FIFO_INF); + if ((status & SMCS9118_TX_SPACE_MASK) < length) + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("eth -- Error... Send KErrSMCS9118TxOutOfMenory"); + #endif + DriverUnlock(irq); + return KErrTxOutOfMemory; + } + + status = (length & 0x7ff) | SMCS9118_TX_FIRSTSEG | SMCS9118_TX_LASTSEG; + Write32(SMCS9118_TX_DATA_FIFO, status); + status = (length & 0x7ff) | SMCS9118_TX_PKT_TAG; + Write32(SMCS9118_TX_DATA_FIFO, status); + + // calculate number of full words + remaining bytes + + TUint32 words = length >> 2; + TUint32 bytes = length & 3; + + // write words + while (words--) + { + Write32(SMCS9118_TX_DATA_FIFO, *dataP++); + } + + // write bytes + if (bytes) + { + TUint8 *dataBytes = (TUint8*) dataP; + status = 0; + switch (bytes) + { + case 3: + status |= dataBytes[2] << 16; + // fallthrough + case 2: + status |= dataBytes[1] << 8; + // fallthrough + case 1: + status |= dataBytes[0]; + } + Write32(SMCS9118_TX_DATA_FIFO, status); + } + + // Clear interrupt + TUint32 retries = SMCS9118_MAX_RETRIES; + while(retries-- && !((status = Read32(SMCS9118_INT_STS)) & SMCS9118_INT_STS_TX)) + { + ByteTestDelay(1); // delay + } + if (retries == 0 || (status & SMCS9118_INT_STS_TXE)) + { + DriverUnlock(irq); + return KErrGeneral; + } + Write32(SMCS9118_INT_STS, SMCS9118_INT_STS_TX); + ByteTestDelay(2); + + DriverUnlock(irq); + return KErrNone; + } + +TInt DEthernetSMCS9118Pdd::DiscardFrame() +/** + * Discard the frame by fast forwarding over it + * + * Optional: if this doesn't + * clear the frame, stop the receiver, dump the whole RX FIFO + * and restart the receiver + * assume iDriverLock held + */ + { + TUint32 retries = SMCS9118_MAX_RETRIES; + + // if it is 4 words or less then just read it + TInt32 status = Read32(SMCS9118_RX_STATUS); + TInt32 length = (status >> SMCS9118_RX_LEN_SHIFT) & SMCS9118_RX_LEN_MASK; + TInt32 words = length >> 2; + if (length & 3) + { + words++; + } + if (words <= 4) + { + while (words--) + { + status = Read32(SMCS9118_RX_DATA_FIFO); + } + status = Read32(SMCS9118_RX_DATA_FIFO); + return KErrNone; + } + + // FFWD over the frame + Write32(SMCS9118_RX_DP_CTL, SMCS9118_RX_DP_FFWD); + ByteTestDelay(1); + while((Read32(SMCS9118_RX_DP_CTL) & SMCS9118_RX_DP_FFWD) && --retries) + { + ByteTestDelay(1); // delay + } + if (retries != 0) + { + return KErrNone; + } + +#ifdef SMCS9118_DUMP_FIFO + // stop the receiver + TUint32 status; + TInt32 err; + err = ReadMac(SMCS9118_MAC_CR, status); + if (err != KErrNone) + { + return err; + } + status &= ~SMCS9118_MAC_RXEN; + err = WriteMac(SMCS9118_MAC_CR, status); + if (err != KErrNone) + { + return err; + } + + // wait for reciever to stop + retries = SMCS9118_MAX_RETRIES; + Write32(SMCS9118_RX_DP_CTL, SMCS9118_RX_DP_FFWD); + ByteTestDelay(2); + while((Read32(SMCS9118_INT_STS) & SMCS9118_RXSTOP_INT) && --retries) + { + ByteTestDelay(1); // delay + } + if (retries == 0) + { + return KErrGeneral; + } + + // dump the whole FIFO + retries = SMCS9118_MAX_RETRIES; + Write32(SMCS9118_RX_CFG, SMCS9118_RX_DUMP); + ByteTestDelay(1); + while((Read32(SMCS9118_RX_CFG) & SMCS9118_RX_DUMP) && --retries) + { + ByteTestDelay(1); // delay + } + if (retries != 0) + { + // re-enable RX + err = ReadMac(SMCS9118_MAC_CR, status); + if (err != KErrNone) + { + return err; + } + status |= SMCS9118_MAC_RXEN; + err = WriteMac(SMCS9118_MAC_CR, status); + return err; + } +#endif + return KErrGeneral; + } + + + +TInt DEthernetSMCS9118Pdd::ReceiveFrame(TBuf8& aBuffer, TBool aOkToUse) +/** + * Retrieve data from the device - called by the RxDFC queued by the (variant's) ISR. + * Pull the received data out of the device and into the supplied buffer. + * Need to be told if the buffer is OK to use as if it not we could dump + * the waiting frame in order to clear the interrupt if necessory. + * @param aBuffer Reference to the buffer to be used to store the data in + * @param aOkToUse Bool to indicate if the buffer is usable + * @return KErrNone if the buffer has been filled. + */ + { + TInt32 status; + TUint32 length; + + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetSMCS9118Pdd::ReceiveFrame()"); + #endif + // Always request for power (Needs to be done incase of external wakeup event) + iPowerHandler.RequestPower(); + + TInt irq = DriverLock(); + // If no buffer available dump frame + if (!aOkToUse) + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("SMCS9118: No Rx buffer available"); + #endif + + if ((status = DiscardFrame()) == KErrNone) + { + status = KErrGeneral; + } + DriverUnlock(irq); + return status; + } + + + status = Read32(SMCS9118_RX_FIFO_INF); + if(!(status & 0xffff)) + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("SMCS9118: Empty Rx FIFO"); + #endif + DriverUnlock(irq); + return KErrGeneral; + } + + // discard bad packets + status = Read32(SMCS9118_RX_STATUS); + length = (status >> SMCS9118_RX_LEN_SHIFT) & SMCS9118_RX_LEN_MASK; + if (status & SMCS9118_RX_ES) + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("SMCS9118: Bad Rx Packet"); + #endif + + if ((status = DiscardFrame()) == (TUint32)KErrNone) + { + status = KErrGeneral; + } + DriverUnlock(irq); + return status; + } + + TUint32 words = length >> 2; + TUint32 *dataP = (TUint32*) aBuffer.Ptr(); + + if (length & 3) + { + words++; + } + + while (words--) + { + *dataP++ = Read32(SMCS9118_RX_DATA_FIFO); + } + aBuffer.SetLength(length-4); + + DriverUnlock(irq); + return KErrNone; + } + + +const TInt KEthernetDfcThreadPriority = 24; +_LIT(KEthernetDfcThread,"EthernetDfcThread"); + + +TInt DEthernetSMCS9118Pdd::DoCreate() +/** + * Does the hard and soft reset of the lan card. + * Puts the default configuration in iDefaultConfig member + */ + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetSMCS9118Pdd::DoCreate()"); + #endif + + + // Register the power handler with Symbian Power Framework + iPowerHandler.Add(); + TInt r = iPowerHandler.SetEthernetPdd(this); + #if defined(INSTR) && defined(KTRACE_SYNCH) + __KTRACE_OPT(KPOWER, Kern::Printf("iPowerHandler.SetEthernetPdd() returned [%d]",r)); + #endif + + // Allocate a kernel thread to run the DFC + r = Kern::DynamicDfcQCreate(iDfcQ, KEthernetDfcThreadPriority, KEthernetDfcThread); + + if (r != KErrNone) + { + return r; + } + +#ifdef CPU_AFFINITY_ANY + NKern::ThreadSetCpuAffinity((NThread*) iDfcQ->iThread, KCpuAffinityAny); +#endif + + iRxDfc.SetDfcQ(iDfcQ); + + TInt irq = DriverLock(); + iDefaultConfig.iEthSpeed = KEthSpeed10BaseT; + iDefaultConfig.iEthDuplex = KEthDuplexHalf; + + // detect if SMSC9118 card is available, ignore revision + TUint32 id = Read32(SMCS9118_ID_REV) & SMCS9118_ID_MASK; + if(id != SMCS9118_ID_VAL) + { + DriverUnlock(irq); + return KErrHardwareNotAvailable; + } + + TUint32 mac; + r = ReadMac(SMCS9118_MAC_ADDRL, mac); + if (r != KErrNone) + { + DriverUnlock(irq); + return r; + } + + iDefaultConfig.iEthAddress[0] = (TUint8)(mac); + iDefaultConfig.iEthAddress[1] = (TUint8)(mac>>8); + iDefaultConfig.iEthAddress[2] = (TUint8)(mac>>16); + iDefaultConfig.iEthAddress[3] = (TUint8)(mac>>24); + r = ReadMac(SMCS9118_MAC_ADDRH, mac); + if (r != KErrNone) + { + DriverUnlock(irq); + return r; + } + iDefaultConfig.iEthAddress[4] = (TUint8)(mac); + iDefaultConfig.iEthAddress[5] = (TUint8)(mac>>8); + + // Serial number is the bottom 4 bytes of the MAC address + TInt serialNum = (iDefaultConfig.iEthAddress[2] << 24) + | (iDefaultConfig.iEthAddress[3] << 16) + | (iDefaultConfig.iEthAddress[4] << 8) + | (iDefaultConfig.iEthAddress[5] ); + + // Push the serial numberinto the variant config so it can be retrieved via HAL + NE1_TBVariant::SetSerialNumber(serialNum); + + iInterruptId = KEthernetInterruptId; + + DriverUnlock(irq); + __KTRACE_OPT(KHARDWARE, Kern::Printf("-- MAC address %2x.%2x.%2x.%2x.%2x.%2x", + iDefaultConfig.iEthAddress[0], iDefaultConfig.iEthAddress[1], + iDefaultConfig.iEthAddress[2], iDefaultConfig.iEthAddress[3], + iDefaultConfig.iEthAddress[4], iDefaultConfig.iEthAddress[5])); + + // Register ISR + r = BindInterrupt(KEthernetInterruptId, Isr, this); + if(r != KErrNone) + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("-- Error!!! Ethernet failed to bind interrupt."); + #endif + return r; + } + return r; + } + +void DEthernetSMCS9118Pdd::Sleep() +/** + * Put the card into D1 sleep + * assume iDriverLock not held + */ + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetSMCS9118Pdd::Sleep()"); + #endif + + TUint32 status; + TInt irq = DriverLock(); + status = Read32(SMCS9118_PMT_CTRL) | SMCS9118_PM_MODE_D1; + Write32(SMCS9118_PMT_CTRL, status); + DriverUnlock(irq); + } + +TInt DEthernetSMCS9118Pdd::Wakeup() +/** + * Wake the card up + * assume iDriverLock not held + */ + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetSMCS9118Pdd::Wakeup()"); + #endif + + TUint32 status; + + // has card woken up yet ? + + TInt irq = DriverLock(); + TUint32 retry = SMCS9118_MAX_RETRIES; + do + { + Write32(SMCS9118_BYTE_TEST, 0x12345678); + status = Read32(SMCS9118_PMT_CTRL); + if (status & SMCS9118_PMT_READY) + { + break; + } + Kern::NanoWait(ONE_MSEC); + } while (--retry); + + if (retry == 0) + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("-- Error!!! Problem in Wakeup of SMCS9118 card."); + #endif + DriverUnlock(irq); + return KErrGeneral; + } + DriverUnlock(irq); + return KErrNone; + } + +TInt DEthernetSMCS9118Pdd::CardSoftReset() +/** + * Does the soft reset of the lan card + * assume iDriverLock not held + */ + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetSMCS9118Pdd::CardSoftReset()"); + #endif + + TInt32 status; + + // wake the card up + status = Wakeup(); + if (status != KErrNone) + { + return status; + } + + // do soft reset + TInt irq = DriverLock(); + status = Read32(SMCS9118_HW_CFG); + status |= SMCS9118_HW_CFG_SRST; + Write32(SMCS9118_HW_CFG, status); + + ByteTestDelay(1); + + TUint32 retry = SMCS9118_MAX_RETRIES; + do + { + status = Read32(SMCS9118_HW_CFG); + if (!(status & SMCS9118_HW_CFG_SRST)) + { + break; + } + Kern::NanoWait(ONE_MSEC); + } while (--retry); + + if (retry == 0) + { + DriverUnlock(irq); + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("-- Error!!! Problem in soft reset of SMCS9118 card."); + #endif + return KErrGeneral; + } + + ByteTestDelay(1); + DriverUnlock(irq); + + return KErrNone; + } + + +/** + * service the Isr + */ +void DEthernetSMCS9118Pdd::Isr(TAny* aPtr) + { + + DEthernetSMCS9118Pdd &d=*(DEthernetSMCS9118Pdd*)aPtr; + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetSMCS9118Pdd::Isr"); + #endif + + // get interrupt status + TUint32 status = d.Read32(SMCS9118_INT_STS); + + if (d.IsReady() && (status & SMCS9118_INT_STS_RSFL)) + { + // We received an Rx Interrupt, so clear it + // and queue on dfc + d.Write32(SMCS9118_INT_EN, 0); + d.iRxDfc.Add(); + } + else + { + // spurious interrupt ? + d.Write32(SMCS9118_INT_STS, status); + } + d.ClearInterrupt(d.iInterruptId); + } + +// +// Queued by the ISR on a receive interrupt. Calls into LDD which calls back into +// PDD.ReceiveFrame() to get the data and write it into the LDD managed FIFO. +// Assume iDriverLock not held +// + +void DEthernetSMCS9118Pdd::ServiceRxDfc(TAny* aPtr) + { + #if defined(INSTR) && defined(KTRACE_SYNCH) + KPROFILE_PRINT("DEthernetSMCS9118Pdd::ServiceRxDfc"); + #endif + + DEthernetSMCS9118Pdd &d=*(DEthernetSMCS9118Pdd*)aPtr; + + d.ReceiveIsr(); + + TInt irq = d.DriverLock(); + // reset status + d.Write32(SMCS9118_INT_STS, SMCS9118_INT_STS_RSFL); + d.ByteTestDelay(2); + + // reenable interrupt + d.Write32(SMCS9118_INT_EN, SMCS9118_INT_EN_RSFL); + d.ByteTestDelay(1); + d.DriverUnlock(irq); + + return; + } + +/** + * Read a MAC register + * assume iDriverLock held + */ +TInt32 DEthernetSMCS9118Pdd::ReadMac(TUint32 aReg, TUint32 &aVal) + { + TUint32 timeout; + + for(timeout = 0; timeout < SMCS9118_MAC_TIMEOUT; timeout ++) + { + if(Read32(SMCS9118_MAC_CSR_CMD) & SMCS9118_MAC_CSR_BUSY) + { + Kern::NanoWait(ONE_MSEC); + } + } + + TUint32 cmd = 0; + + Write32(SMCS9118_MAC_CSR_CMD, cmd); + ByteTestDelay(1); + + cmd = (aReg & 0xff) | SMCS9118_MAC_CSR_BUSY | SMCS9118_MAC_CSR_READ; + + Write32(SMCS9118_MAC_CSR_CMD, cmd); + ByteTestDelay(1); + + for(timeout = 0; timeout < SMCS9118_MAC_TIMEOUT; timeout ++) + { + if(Read32(SMCS9118_MAC_CSR_CMD) & SMCS9118_MAC_CSR_BUSY) + { + Kern::NanoWait(ONE_MSEC); + } + else + { + aVal = Read32(SMCS9118_MAC_CSR_DATA); + return KErrNone; + } + } + return KErrTimedOut; + } + +/** + * Write a MAC register + * assume iDriverLock held + */ +TInt32 DEthernetSMCS9118Pdd::WriteMac(TUint32 aReg, TUint32 aVal) + { + if (Read32(SMCS9118_MAC_CSR_CMD) & SMCS9118_MAC_CSR_BUSY) + { + return KErrTimedOut; + } + + TUint32 cmd = 0; + TUint32 timeout; + + Write32(SMCS9118_MAC_CSR_CMD, cmd); + ByteTestDelay(1); + + cmd = (aReg & 0xff) | SMCS9118_MAC_CSR_BUSY; + + Write32(SMCS9118_MAC_CSR_DATA, aVal); + ByteTestDelay(1); + Write32(SMCS9118_MAC_CSR_CMD, cmd); + ByteTestDelay(1); + + for (timeout = 0; timeout < SMCS9118_MAC_TIMEOUT; timeout ++) + { + if(Read32(SMCS9118_MAC_CSR_CMD) & SMCS9118_MAC_CSR_BUSY) + { + Kern::NanoWait(ONE_MSEC); + } + else + { + return KErrNone; + } + } + return KErrTimedOut; + } + +/** + * Read a PHY register + * assume iDriverLock held + */ +TInt32 DEthernetSMCS9118Pdd::ReadPhy(TUint32 aReg, TUint32 &aValue) + { + TUint32 cmd; + TUint32 timeout; + TInt32 err; + + // bail out if busy + err = ReadMac(SMCS9118_MAC_MII_ACC, aValue); + if (err != KErrNone) + { + return err; + } + + if (aValue & SMCS9118_MII_BUSY) + { + return KErrTimedOut; + } + + cmd = SMCS9118_PHY_ADDR | (aReg << 6) | SMCS9118_MII_BUSY; + + err = WriteMac(SMCS9118_MAC_MII_ACC, cmd); + if (err != KErrNone) + { + return err; + } + + for(timeout = 0; timeout < SMCS9118_MAC_TIMEOUT; timeout++) + { + err = ReadMac(SMCS9118_MAC_MII_ACC, aValue); + if (err != KErrNone) + { + return err; + } + + if (!(aValue & SMCS9118_MII_BUSY)) + { + err = ReadMac(SMCS9118_MAC_MII_DATA, aValue); + return err; + } + } + return KErrTimedOut; + } + +/** + * Write a PHY register + * assume iDriverLock held + */ +TInt32 DEthernetSMCS9118Pdd::WritePhy(TUint32 aReg, TUint32 aVal) + { + TUint32 cmd; + TUint32 timeout; + TUint32 status; + TInt32 err; + + // bail out if busy + err = ReadMac(SMCS9118_MAC_MII_ACC, status); + if (err != KErrNone) + { + return err; + } + + if (status & SMCS9118_MII_BUSY) + { + return KErrTimedOut; + } + + cmd = SMCS9118_PHY_ADDR | (aReg << 6) | SMCS9118_MII_WRITE | SMCS9118_MII_BUSY; + + err = WriteMac(SMCS9118_MAC_MII_DATA, aVal & 0xffff); + if (err != KErrNone) + { + return err; + } + err = WriteMac(SMCS9118_MAC_MII_ACC, cmd); + if (err != KErrNone) + { + return err; + } + + for(timeout = 0; timeout < SMCS9118_MAC_TIMEOUT; timeout++) + { + err = ReadMac(SMCS9118_MAC_MII_ACC, status); + if (err != KErrNone) + { + return err; + } + if(!(status & SMCS9118_MII_BUSY)) + { + return KErrNone; + } + } + return KErrTimedOut; + } +// PDD entry point +DECLARE_STANDARD_PDD() + { + return new DEthernetPddFactory; + } diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/ethernet/smcs9118_ethernet.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/ethernet/smcs9118_ethernet.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,370 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\ethernet\smcs9118_ethernet.h +* SMCS9118 Ethernet driver header +* +*/ + + + + +#ifndef __SMCS9118_ETHERNET_H__ +#define __SMCS9118_ETHERNET_H__ + +#include +#include "shared_ethernet.h" +#include +#include + +/** + * @addtogroup shared_ethernet + * @{ + */ + +// +// Driver Constants +// + +_LIT(KEthernetPddName,"Ethernet.Navi9118"); + +// +// SMCS9118 FIFO Registers (see datasheet Figure 5.1) +// +const TUint32 SMCS9118_RX_DATA_FIFO = (TUint32)(KHwBaseEthernet + 0x00); +const TUint32 SMCS9118_TX_DATA_FIFO = (TUint32)(KHwBaseEthernet + 0x20); +const TUint32 SMCS9118_RX_STATUS = (TUint32)(KHwBaseEthernet + 0x40); +const TUint32 SMCS9118_RX_STATUS_PEEK = (TUint32)(KHwBaseEthernet + 0x44); +const TUint32 SMCS9118_TX_STATUS = (TUint32)(KHwBaseEthernet + 0x48); +const TUint32 SMCS9118_TX_STATUS_PEEK = (TUint32)(KHwBaseEthernet + 0x4c); + +// +// SMSC9118 System Control and Status Registers - see datasheet section 5.3 +// +const TUint32 SMCS9118_ID_REV = (TUint32)(KHwBaseEthernet + 0x50); +const TUint32 SMCS9118_IRQ_CFG = (TUint32)(KHwBaseEthernet + 0x54); +const TUint32 SMCS9118_INT_STS = (TUint32)(KHwBaseEthernet + 0x58); +const TUint32 SMCS9118_INT_EN = (TUint32)(KHwBaseEthernet + 0x5c); +const TUint32 SMCS9118_BYTE_TEST = (TUint32)(KHwBaseEthernet + 0x64); +const TUint32 SMCS9118_FIFO_INT = (TUint32)(KHwBaseEthernet + 0x68); +const TUint32 SMCS9118_RX_CFG = (TUint32)(KHwBaseEthernet + 0x6c); +const TUint32 SMCS9118_TX_CFG = (TUint32)(KHwBaseEthernet + 0x70); +const TUint32 SMCS9118_HW_CFG = (TUint32)(KHwBaseEthernet + 0x74); +const TUint32 SMCS9118_RX_DP_CTL = (TUint32)(KHwBaseEthernet + 0x78); +const TUint32 SMCS9118_RX_FIFO_INF = (TUint32)(KHwBaseEthernet + 0x7c); +const TUint32 SMCS9118_TX_FIFO_INF = (TUint32)(KHwBaseEthernet + 0x80); +const TUint32 SMCS9118_PMT_CTRL = (TUint32)(KHwBaseEthernet + 0x84); +const TUint32 SMCS9118_GPIO_CFG = (TUint32)(KHwBaseEthernet + 0x88); +const TUint32 SMCS9118_GPT_CFG = (TUint32)(KHwBaseEthernet + 0x8c); +const TUint32 SMCS9118_GPT_CNT = (TUint32)(KHwBaseEthernet + 0x90); +const TUint32 SMCS9118_WORDSWAP = (TUint32)(KHwBaseEthernet + 0x98); +const TUint32 SMCS9118_FREE_RUN = (TUint32)(KHwBaseEthernet + 0x9c); +const TUint32 SMCS9118_RX_DROP = (TUint32)(KHwBaseEthernet + 0xa0); +const TUint32 SMCS9118_MAC_CSR_CMD = (TUint32)(KHwBaseEthernet + 0xa4); +const TUint32 SMCS9118_MAC_CSR_DATA = (TUint32)(KHwBaseEthernet + 0xa8); +const TUint32 SMCS9118_AFC_CFG = (TUint32)(KHwBaseEthernet + 0xac); +const TUint32 SMCS9118_E2P_CMD = (TUint32)(KHwBaseEthernet + 0xb0); +const TUint32 SMCS9118_E2P_DATA = (TUint32)(KHwBaseEthernet + 0xb0); + +// +// SMCS9118 MAC CSR register map - see datasheet section 5.4 +// +const TUint32 SMCS9118_MAC_CR = 0x01; +const TUint32 SMCS9118_MAC_ADDRH = 0x02; +const TUint32 SMCS9118_MAC_ADDRL = 0x03; +const TUint32 SMCS9118_MAC_MII_ACC = 0x06; +const TUint32 SMCS9118_MAC_MII_DATA = 0x07; +const TUint32 SMCS9118_MAC_FLOW = 0x08; +const TUint32 SMCS9118_MAC_VLAN1 = 0x09; +const TUint32 SMCS9118_MAC_VLAN2 = 0x0a; +const TUint32 SMCS9118_MAC_WUFF = 0x0b; +const TUint32 SMCS9118_MAC_WUCSR = 0x0c; + +// +// SMCS9118 PHY control and status registers - see datasheet section 5.5 +// +const TUint32 SMCS9118_PHY_BCR = 0x00; +const TUint32 SMCS9118_PHY_BSR = 0x01; +const TUint32 SMCS9118_PHY_ID1 = 0x02; +const TUint32 SMCS9118_PHY_ID2 = 0x03; +const TUint32 SMCS9118_PHY_AUTONEG_AD = 0x04; +const TUint32 SMCS9118_PHY_AUTONEG_LPAR = 0x05; +const TUint32 SMCS9118_PHY_AUTONEG_ER = 0x06; +const TUint32 SMCS9118_PHY_MCSR = 0x11; +const TUint32 SMCS9118_PHY_SMR = 0x12; +const TUint32 SMCS9118_PHY_SCSI = 0x1b; +const TUint32 SMCS9118_PHY_ISR = 0x1d; +const TUint32 SMCS9118_PHY_IMR = 0x1e; +const TUint32 SMCS9118_PHY_SCSR = 0x1f; + +// +// SMCS9118 system register values - see datasheet section 3.12.2 +// +const TUint32 SMCS9118_TX_FIRSTSEG = 0x00002000; // +const TUint32 SMCS9118_TX_LASTSEG = 0x00001000; // + +const TUint32 SMCS9118_RX_ES = 0x00008000; // RX Error Status - see datasheet section 3.13.3 + +const TUint32 SMCS9118_ID_VAL = 0x01180000; // Chip ID = 0x0118 +const TUint32 SMCS9118_ID_MASK = 0xffff0000; // chip id is top 16bits +const TUint32 SMCS9118_REV_MASK = 0x0000ffff; // chip revision is bottom 16bits + +// IRQ_CFG values - see datasheet section 5.3.2 +const TUint32 SMCS9118_IRQ_CFG_DEAS = 0x16000000; // Interupt deassert interval +const TUint32 SMCS9118_IRQ_CFG_TYPE = 0x00000111; // IRQ_TYPE active low, push-pull + +// INT_STS values - see datasheet section 5.3.3 +const TUint32 SMCS9118_INT_STS_RSFL = 0x00000008; // RX Status FIFO Level Int +const TUint32 SMCS9118_RXSTOP_INT = 0x00100000; // RX Status FIFO Level Int +const TUint32 SMCS9118_INT_STS_TXE = 0x00002000; // TX error +const TUint32 SMCS9118_INT_STS_TX = 0x02212f80; // + +// INT_EN values - see datasheet section 5.3.4 +const TUint32 SMCS9118_INT_EN_RSFL = 0x00000008; // RX Status FIFO Level Int + +// RX_CFG - see datasheet section 5.3.7 +const TUint32 SMCS9118_RX_DUMP = 0x00008000; // RX dump whole FIFO + +// TX_CFG - see datasheet section 5.3.8 +const TUint32 SMCS9118_TX_CFG_TXSAO = 0x00000004; // TX Status allow overrun +const TUint32 SMCS9118_TX_CFG_TX_ON = 0x00000002; // TX ON + +// HW_CFG - see datasheet section 5.3.9 +const TUint32 SMCS9118_HW_CFG_SRST = 0x00000001; // Software Reset Time-out +const TUint32 SMCS9118_HW_CFG_SF = 0x00100000; // SF - Store and forward + +// TX FIFO Allocations - see datasheet section 5.3.9.1 +const TUint32 SMCS9118_TX_FIFO_SZ = 0x03<<16; // bits 16:19 determine FIFO size +const TUint32 SMCS9118_TX_PKT_TAG = 0xabcd0000; + +// RX FIFO - see datasheet section 5.3.10/5.3.11 +const TUint32 SMCS9118_RX_DP_FFWD = 0x80000000; // RX Data FIFO Fast Forward +const TUint32 SMCS9118_RX_LEN_MASK = 0x0000ffff; +const TUint32 SMCS9118_RX_LEN_SHIFT = 0x10; + +// TX FIFO - see datasheet section 5.3.12 +const TUint32 SMCS9118_TX_SPACE_MASK = 0x0000ffff; +const TUint32 SMCS9118_TX_USED_MASK = 0x00ff0000; + +// PMT_CTRL - see datasheet section 5.3.13 +const TUint32 SMCS9118_PMT_PHY_RST = 0x00000400; // Physical reset +const TUint32 SMCS9118_PMT_READY = 0x00000001; // Device ready +const TUint32 SMCS9118_PM_MODE_D1 = 0x00001000; // D1 Sleep +const TUint32 SMCS9118_PM_MODE_D2 = 0x00002000; // D2 Sleep + +// GPIO_CFG - - see datasheet section 5.3.14 +const TUint32 SMCS9118_GPIO_LED_EN = 0x70000000; // LED on +const TUint32 SMCS9118_GPIO_GPIOBUF = 0x00070000; // GPIO Buffer Type + +// MAC_CSR_CMD - see datasheet section 5.3.20 +const TUint32 SMCS9118_MAC_CSR_BUSY = 0x80000000; +const TUint32 SMCS9118_MAC_CSR_READ = 0x40000000; + +// Auto Flow Control Config Register - see datasheet section 5.3.22 +// BACK_DUR = 4 +// AFC_LO = 0x37 +// AFC_HI = 0x6e +const TUint32 SMCS9118_AFC_CFG_VAL = 0x006e3740; + +// EEPROM Command Register - see datasheet section 5.3.23 +const TUint32 SMCS9118_E2P_CMD_BUSY = 0x80000000; + +// SMCS9118 MAC control register values - see datasheet section 5.4.1 +const TUint32 SMCS9118_MAC_RXALL = 0x80000000; +const TUint32 SMCS9118_MAC_TXEN = 0x00000008; +const TUint32 SMCS9118_MAC_RXEN = 0x00000004; + +// SMCS9118 MII access register values - see datasheet section 5.4.6 +const TUint32 SMCS9118_PHY_ADDR = 0x00000800; +const TUint32 SMCS9118_MII_WRITE = 0x00000002; +const TUint32 SMCS9118_MII_BUSY = 0x00000001; + + +// SMCS9118 PHY Basic Control register values - see datasheet section 5.5.1 +const TUint32 SMCS9118_PHY_ANEG_EN = 0x00001000; // Auto negotiate enable +const TUint32 SMCS9118_PHY_ANEG_RESTART = 0x00000200; // Auto negotiate restart + +// SMCS9118 PHY Basic Status register values - see datasheet section 5.5.2 +const TUint32 SMCS9118_PHY_ANEG_CMPL = 0x00000020; // Auto negotiate complete + +// SMCS9118 PHY auto negotiate advertisement values - see datasheet section 5.5.5 +const TUint32 SMCS9118_PHY_10BT = 0x00000020; +const TUint32 SMCS9118_PHY_10BTFD = 0x00000040; +const TUint32 SMCS9118_PHY_100BTX = 0x00000080; +const TUint32 SMCS9118_PHY_100BTXFD = 0x00000100; +const TUint32 SMCS9118_PHY_PAUSE = 0x00000C00; +const TUint32 SMCS9118_PHY_DEF_ANEG = SMCS9118_PHY_10BT | + SMCS9118_PHY_10BTFD | + SMCS9118_PHY_100BTX | + SMCS9118_PHY_100BTXFD | + SMCS9118_PHY_PAUSE; + +const TUint32 KEthernetInterruptId = KGpio_Ethernet_Int_Pin; + +const TUint32 SMCS9118_LOCK_ORDER = 0x03u; + +// + +class DEthernetPddFactory : public DPhysicalDevice +/** +Ethernet PDD factory class +*/ + { +public: + DEthernetPddFactory(); + + virtual TInt Install(); + virtual void GetCaps(TDes8& aDes) const; + virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); + virtual TInt Validate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); + }; //DEthernetPddFactory + + + + +class DEthernetSMCS9118Pdd : public DEthernetPdd +/** +Ethernet PDD class. +*/ + { +public: + DEthernetSMCS9118Pdd(); + ~DEthernetSMCS9118Pdd(); + + static void Isr(TAny* aPtr); + + /** + * Stop receiving frames + * @param aMode The stop mode + */ + void Stop(TStopMode aMode); + + /** + * Configure the device + * Reconfigure the device using the new configuration supplied. + * This should not change the MAC address. + * @param aConfig The new configuration + * @see ValidateConfig() + * @see MacConfigure() + */ + TInt Configure(TEthernetConfigV01 &aConfig) ; + /** + * Change the MAC address + * Attempt to change the MAC address of the device + * @param aConfig A Configuration containing the new MAC + * @see Configure() + */ + void MacConfigure(TEthernetConfigV01 &aConfig) ; + + /** + * Transmit data + * @param aBuffer referance to the data to be sent + * @return KErrNone if the data has been sent + */ + TInt Send(TBuf8 &aBuffer) ; + /** + * Retrieve data from the device + * Pull the received data out of the device and into the supplied buffer. + * Need to be told if the buffer is OK to use as if it not we could dump + * the waiting frame in order to clear the interrupt if necessory. + * @param aBuffer Referance to the buffer to be used to store the data in + * @param okToUse Bool to indicate if the buffer is usable + * @return KErrNone if the buffer has been filled. + */ + TInt ReceiveFrame(TBuf8 &aBuffer, + TBool okToUse) ; + + TInt DoCreate(); + + /** + * Put the card to sleep + */ + + void Sleep(); + /** + * Wake the card up + */ + TInt Wakeup(); + +protected: + /** + * Discard a frame + */ + TInt DiscardFrame(); + + static void ServiceRxDfc(TAny *aPtr); + + /** + * Does the soft reset of the lan card + */ + TInt CardSoftReset(); + + inline TInt32 IsReady(); + /** + * see data sheet section 6.1, Host Interface Timing + * "dummy" reads of the BYTE_TEST register will + * guarantee the minimum write-to-read timing restrictions + * as listed in Table 6.1 + */ + inline void ByteTestDelay(TUint32 aCount); + + /** + * Read/Write the MAC registers + */ + TInt32 ReadMac(TUint32 aReg, TUint32 &aVal); + TInt32 WriteMac(TUint32 aReg, TUint32 aVal); + + /** + * Read/Write the PHY registers + */ + TInt32 ReadPhy(TUint32 aReg, TUint32 &aVal); + TInt32 WritePhy(TUint32 aReg, TUint32 aVal); + + /** + * Read a 32bit register + */ + inline TUint32 Read32(TUint32 aReg); + + /** + * Write a 32bit register + */ + inline void Write32(TUint32 aReg, TUint32 aVal); + + /** + * Interrupt handling + */ + inline void ClearInterrupt(TInt aId); + inline void UnbindInterrupt(TInt aId); + inline TInt BindInterrupt(TInt aId, TGpioIsr aIsr, TAny *aPtr); + inline TInt EnableInterrupt(TInt aId); + inline TInt DisableInterrupt(TInt aId); + + /** + * lock handling + */ + inline TInt DriverLock(); + inline void DriverUnlock(TInt); + +protected: + TDfc iRxDfc; +#ifdef __SMP__ + TSpinLock *iDriverLock; +#endif + }; + +#include "smcs9118_ethernet.inl" + +/** @} */ + +#endif //__SMCS9118_ETHERNET_H__ diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/ethernet/smcs9118_ethernet.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/ethernet/smcs9118_ethernet.inl Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,95 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +inline TInt32 DEthernetSMCS9118Pdd::IsReady() + { + return iReady; + } + +/** + * see data sheet section 6.1, Host Interface Timing + * "dummy" reads of the BYTE_TEST register will + * guarantee the minimum write-to-read timing restrictions + * as listed in Table 6.1 + */ +inline void DEthernetSMCS9118Pdd::ByteTestDelay(TUint32 aCount) + { + TUint32 i; + + for (i = 0; i< aCount; i++) + { + AsspRegister::Read32(SMCS9118_BYTE_TEST); + } + } + +/** + * Read a 32bit register + */ +inline TUint32 DEthernetSMCS9118Pdd::Read32(TUint32 aReg) + { + return AsspRegister::Read32(aReg); + } + +/** + * Write a 32bit register + */ +inline void DEthernetSMCS9118Pdd::Write32(TUint32 aReg, TUint32 aVal) + { + AsspRegister::Write32(aReg, aVal); + } + +/** + * Interrupt handling + */ +inline void DEthernetSMCS9118Pdd::ClearInterrupt(TInt aId) + { + GPIO::ClearInterrupt(aId); + } + +inline void DEthernetSMCS9118Pdd::UnbindInterrupt(TInt aId) + { + GPIO::UnbindInterrupt(aId); + } + +inline TInt DEthernetSMCS9118Pdd::BindInterrupt(TInt aId, TGpioIsr aIsr, TAny *aPtr) + { + return GPIO::BindInterrupt(aId, aIsr, aPtr); + } + +inline TInt DEthernetSMCS9118Pdd::EnableInterrupt(TInt aId) + { + return GPIO::EnableInterrupt(aId); + } + +inline TInt DEthernetSMCS9118Pdd::DisableInterrupt(TInt aId) + { + return GPIO::DisableInterrupt(aId); + } + +/** + * lock handling + */ +inline TInt DEthernetSMCS9118Pdd::DriverLock() + { + return __SPIN_LOCK_IRQSAVE(*iDriverLock); + } + +inline void DEthernetSMCS9118Pdd::DriverUnlock(TInt irq) + { + __SPIN_UNLOCK_IRQRESTORE(*iDriverLock, irq); + } diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/gpio.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/gpio.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/exlcdne1_tb.mmp +* gpio.dll NE1_TBVariant GPIO driver +* +*/ + + + +/** + @file +*/ +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(gpio,dll) +targettype kext +linkas gpio.dll +romtarget gpio.dll + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +//systeminclude /epoc32/include/ne1_tb +//systeminclude /epoc32/include/ne1_tb/specific + +sourcepath ../naviengine_assp +source gpio.cpp +source staticextension.cpp + +library VariantTarget(ecust,lib) +library resman.lib + +deffile ./~/gpio.def +nostrictdef + +epocallowdlldata + +uid 0x1000008d 0x100039e8 + +VENDORID 0x70000001 + +capability all +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/hal/config.hcf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/hal/config.hcf Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,119 @@ +EManufacturer=0 +EManufacturerHardwareRev=0 +EManufacturerSoftwareRev=0 +EManufacturerSoftwareBuild=0 +EModel=0 +EMachineUid=0 +EDeviceFamily=0 +EDeviceFamilyRev=0 +ECPU=0 +ECPUArch=0 +ECPUABI=0 +ECPUSpeed=GetCPUSpeed +ECpuProfilingDefaultInterruptBase=GetCPUProfilerInterrupt +ESystemStartupReason=GetSystemStartupReason +ESystemException=GetSystemException +ESystemTickPeriod=0 +EMemoryRAM=GetRAMSize +EMemoryRAMFree=GetFreeRAM +EMemoryROM=GetROMSize +EMemoryPageSize=0 +EPowerGood=GetPowerGoodState +EAccessoryPower=GetAccessoryPowerPresent +EPowerBatteryStatus=GetBatteryStatus +EPowerBackup=GetBackupPresent +EPowerBackupStatus=GetBackupStatus +EPowerExternal=GetPowerExternalState +EKeyboard=ProcessKeyboardInfo +EKeyboardState : set = ProcessKeyboardState +EKeyboardDeviceKeys=ProcessKeyboardInfo +EKeyboardAppKeys=ProcessKeyboardInfo +EKeyboardClick=GetKeyboardClickPresent +EKeyboardClickState : set = ProcessKeyboardClickState +EKeyboardClickVolume : set = ProcessKeyboardClickVolume +EKeyboardClickVolumeMax=GetKeyboardClickVolumeMax +EDisplayXPixels=ProcessDisplayCurrentModeInfo +EDisplayYPixels=ProcessDisplayCurrentModeInfo +EDisplayXTwips=ProcessDisplayCurrentModeInfo +EDisplayYTwips=ProcessDisplayCurrentModeInfo +EDisplayColors=ProcessDisplayColors +EDisplayState : set = ProcessDisplayState +EDisplayContrast : set = ProcessDisplayContrast +EDisplayContrastMax=ProcessDisplayMaxContrast +EBacklight=GetBacklightPresent +EBacklightState :set = ProcessBacklightState +EPen=GetPenPresent +EPenX=ProcessPenInfo +EPenY=ProcessPenInfo +EPenState : set = ProcessPenState +EPenDisplayOn : set = ProcessPenDisplayOnState +EPenClick=GetPenClickPresent +EPenClickState : set = ProcessPenClickState +EPenClickVolume : set = ProcessPenClickVolume +EPenClickVolumeMax=GetPenClickVolumeMax +EMouse=GetMousePresent +EMouseX=ProcessMouseInfo +EMouseY=ProcessMouseInfo +EMouseButtons=ProcessMouseInfo +EMouseState : set = ProcessMouseState +EMouseSpeed : set = ProcessMouseSpeed +EMouseAcceleration : set = ProcessMouseAcceleration +EMouseButtonState=GetMouseButtonState +ECaseState=0 +ECaseSwitch=0 +ECaseSwitchDisplayOn=ProcessCaseSwitchDisplayOnState +ECaseSwitchDisplayOff=ProcessCaseSwitchDisplayOffState +ELEDs=GetLedCaps +ELEDmask : set = ProcessLEDMask +ESwitches=GetSwitches +EIntegratedPhone=0 +EDisplayBrightness : set = ProcessDisplayBrightness +EDisplayBrightnessMax=ProcessDisplayMaxBrightness +EKeyboardBacklightState=0 +ELanguageIndex : set = 0 +EKeyboardIndex : set = 0 +EMaxRAMDriveSize=0 +EDisplayIsMono=ProcessDisplaySpecifiedModeInfo +EDisplayIsPalettized=ProcessDisplaySpecifiedModeInfo +EDisplayBitsPerPixel=ProcessDisplaySpecifiedModeInfo +EDisplayNumModes=ProcessDisplayNumModes +EDisplayMemoryAddress=ProcessDisplayCurrentModeInfo +EDisplayOffsetToFirstPixel=ProcessDisplaySpecifiedModeInfo +EDisplayOffsetBetweenLines=ProcessDisplaySpecifiedModeInfo +EDisplayPaletteEntry : set = ProcessDisplayPaletteEntry +EDisplayIsPixelOrderRGB=ProcessDisplayCurrentModeInfo +EDisplayIsPixelOrderLandscape=ProcessDisplayCurrentModeInfo +EDisplayMode : set = ProcessDisplayMode +EDebugPort : set = ProcessDebugPort +ELocaleLoaded=0 +EClipboardDrive=0 +ECustomRestart : set = ProcessCustomRestart +ECustomRestartReason=ProcessCustomRestartReason +EDisplayNumberOfScreens=GetDisplayNumberOfScreens +ESystemDrive : set = 0 +ENanoTickPeriod=ProcessNanoTickPeriod +EFastCounterFrequency=ProcessFastCounterFrequency +EFastCounterCountsUp=0 +EPersistStartupModeKernel : set = ProcessPersistStartupMode +EMaximumCustomRestartReasons = GetMaximumCustomRestartReasons +EMaximumRestartStartupModes = GetMaximumRestartStartupModes +ECustomResourceDrive : set = 0 +ESerialNumber=GetSerialNumber +EPointer3D=Get3DPointerPresent +EPointer3DMaxProximity : set = Process3DRange +EPointer3DThetaSupported=ProcessAdvancedPointer +EPointer3DPhiSupported=ProcessAdvancedPointer +EPointer3DRotationSupported=ProcessAdvancedPointer +EPointer3DPressureSupported=ProcessAdvancedPointer +EPointer3DProximityStep=ProcessAdvancedPointer +EPointerMaxPointers=ProcessAdvancedPointer +EPointerNumberOfPointers : set = ProcessNumberOfPointers +EPointer3DMaxPressure=ProcessAdvancedPointer +EPointer3DPressureStep=ProcessAdvancedPointer +EPointer3DEnterHighPressureThreshold : set = 0 +EPointer3DExitHighPressureThreshold : set = 0 +EPointer3DEnterCloseProximityThreshold : set = 0 +EPointer3DExitCloseProximityThreshold : set = 0 +EHardwareFloatingPoint = GetHardwareFloatingPoint +ENumCpus=GetNumCpus +EDigitiserOrientation : set = DigitiserOrientation diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/hal/hal.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/hal/hal.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* omap_hrp\h4\hal.cpp +* +*/ + + + +#include +#include + +// +TInt GetDisplayNumberOfScreens(TInt /*aDeviceNumber*/, TInt /*aAttrib*/, TBool /*aSet*/, TAny* aInOut) + { + TInt err = KErrNone; + TInt numberOfScreens = 0; + err = UserSvr::HalFunction(EHalGroupVariant, EVariantHalCurrentNumberOfScreens, &numberOfScreens, NULL); + if (err == KErrNone) + { + *(TInt*)aInOut=numberOfScreens; + } + return err; + + } + +TInt GetSerialNumber(TInt /*aDeviceNumber*/, TInt /*aAttrib*/, TBool /*aSet*/, TAny*aInOut) + { + TInt err = KErrNone; + TInt serialNumber = 0; + err = UserSvr::HalFunction(EHalGroupVariant, EVariantHalSerialNumber, &serialNumber, NULL); + if (err == KErrNone) + { + *(TInt*)aInOut=serialNumber; + } + return err; + + } + +TInt GetInterruptNumber(TInt /*aDeviceNumber*/, TInt /*aAttrib*/, TBool /*aSet*/, TAny*aInOut) + { + TInt err = KErrNone; + TInt interruptNumber = 0; + err = UserSvr::HalFunction(EHalGroupVariant, EVariantHalProfilingDefaultInterruptBase, &interruptNumber, NULL); + if (err == KErrNone) + { + *(TInt*)aInOut=interruptNumber; + } + return err; + + } + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/hal/hal.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/hal/hal.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/hal/hal.mmp +* +*/ + + + +#include +target VariantTarget(hal,dll) +targettype dll +linkas hal.dll +noexportlibrary + +sourcepath ../../../../../os/kernelhwsrv/halservices/hal/src +source hal_main.cpp userhal.cpp +sourcepath . +source hal.cpp + +sourcepath /epoc32/build/generatedcpp/hal +source VariantTarget(values,cpp) VariantTarget(config,cpp) + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN +SYMBIAN_BASE_SYSTEMINCLUDE(kernel) + +library euser.lib + +deffile ../../../../../os/kernelhwsrv/halservices/hal/~/hal.def + +uid 0x1000008d 0x100039e8 + +capability all +vendorid 0x70000001 + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/hal/values.hda --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/hal/values.hda Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,34 @@ +EManufacturer=psion +EManufacturerHardwareRev=0 +EManufacturerSoftwareRev=0 +EManufacturerSoftwareBuild=0 +EModel=0 +EMachineUid=NE1_TB +EDeviceFamily=crystal +EDeviceFamilyRev=0 +ECPU=arm +ECPUArch=0 +ECPUABI=arm4 +ESystemTickPeriod=15625 +EMemoryPageSize=0x1000 +ECaseState=0 +ECaseSwitch=0 +EIntegratedPhone=0 +EKeyboardBacklightState=0 +ELanguageIndex=0 +EKeyboardIndex=0 +EMaxRAMDriveSize=0x1000000 +ESystemDrive=0xffff +ELocaleLoaded=0 +EClipboardDrive=2 +EDisplayNumberOfScreens=1 +EFastCounterCountsUp=1 +EPersistStartupModeKernel=0 +ECustomResourceDrive=0xffff +ESerialNumber=0 +EPointer3DEnterHighPressureThreshold=0x7fffffff +EPointer3DExitHighPressureThreshold=-0x7fffffff +EPointer3DEnterCloseProximityThreshold=0x7fffffff +EPointer3DExitCloseProximityThreshold=-0x7fffffff +ENumCpus=1 + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/hcr/hcr.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/hcr/hcr.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file is part of the NE1_TB Variant Base Port +* Hardware Configuration Respoitory Platform Specific Layer (PSL) +* +*/ + +macro HCR_COREIMG_DONTUSE_ROMHDR + + +// -- PIL Statements ---------------------------------------------------------- +// + + +#include "../../../../../os/kernelhwsrv/kernel/eka/drivers/hcr/hcr.mmh" + +// SYSTEM include for path to hcrconfig.h and other hcr headers +VariantIncludePath +AsspIncludePath + +deffile ../../../../../os/kernelhwsrv/kernel/eka/~/hcr.def + +userinclude . +userinclude ../../../../../os/kernelhwsrv/kernel/eka/drivers/hcr + +sourcepath ../../../../../os/kernelhwsrv/kernel/eka/drivers/hcr +source HCR_PIL_SOURCE + + +// -- PSL Statements ---------------------------------------------------------- +// + +sourcepath . +source hcr_psl.cpp +source hcr_psl_config.cpp + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/hcr/hcr_psl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/hcr/hcr_psl.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,205 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file is part of the NE1_TB Variant Base Port +* Hardware Configuration Respoitory Platform Specific Layer (PSL) +* +*/ + + + +#include "hcr_debug.h" + +#include "hcr_hai.h" + +#include "hcr_uids.h" + +#include +#include + +// -- GLOBALS ----------------------------------------------------------------- + + +GLREF_C HCR::SRepositoryCompiled gRepository; +#define BUFFER_OFFSET_ZERO 0 + +// -- CLASSES- ---------------------------------------------------------------- + + +class HCRVariant : public HCR::MVariant + { + +public: + + HCRVariant(); + virtual ~HCRVariant(); + +public: + + TInt Initialise(); + + TBool IgnoreCoreImgRepository(); + TInt GetCompiledRepositoryAddress( TAny* & aAddr); + TInt GetOverrideRepositoryAddress( TAny* & aAddr); + +private: + DChunk * iChunk; + }; + + + + +// -- METHODS ----------------------------------------------------------------- + + +HCRVariant::HCRVariant() + : iChunk(0) + { + HCR_FUNC("HCRVariant"); + } + + +HCRVariant::~HCRVariant() + { + HCR_FUNC("~HCRVariant"); + if (iChunk != 0) + { + NKern::ThreadEnterCS(); + TInt r = Kern::ChunkClose(iChunk); + __NK_ASSERT_ALWAYS(r!=0); + NKern::ThreadLeaveCS(); + } + } + + +TInt HCRVariant::Initialise() + { + HCR_FUNC("HCRVariant::Initialise"); + + HCR_TRACE_RETURN(KErrNone); + } + + +TInt HCRVariant::GetCompiledRepositoryAddress( TAny* & aAddr) + { + HCR_FUNC("HCRVariant::GetCompiledRepositoryAddress"); + + aAddr = static_cast(&gRepository); + HCR_TRACE_RETURN(KErrNone); + } + +TBool HCRVariant::IgnoreCoreImgRepository() + { + HCR_FUNC("HCRVariant::IgnoreCoreImgRepository"); + + HCR_TRACE_RETURN(EFalse); + } + +TInt HCRVariant::GetOverrideRepositoryAddress( TAny* & aAddr) + { + HCR_FUNC("HCRVariant::GetRAMRepositoryAddress"); + + // Note to future implementor: + // #include + // First check to see if SMRIB was created during boot time. + // If SSuperPageBase::iSmrData == KSuperPageAddressFieldUndefined (i.e. -1) + // it does not exist, return KErrNotSupported, SMR not support by base port + // or it is not available due to boot scenario, i.e. boot from MMC + // + // If it does exist (i.e. boot from NAND) then read and process the + // SMR entries listed in the SMRIB looking for KHCRUID_SMRPayloadUID. + // Next using the internal sizes from the HCR dat file within the SMR image + // determine if the RAM holding the SMR image can be shrunk to return + // unused RAM pages at the end of the image. + // + // Finally allocate the reserved RAM identified in the SMR entry to a + // DChunk and return the virtual address of the HCR data file payload + // within the SMR image, i.e. iBase+(sizeof(SSmrRomHeader)>>2). + // Locate SMRIB + const TSuperPage& superpage = Kern::SuperPage(); + TUint32* smrIB; + smrIB = (TUint32 *) superpage.iSmrData; + + HCR_TRACE2("--- Superpage: 0x%08x, SMRIB: 0x%08x", &superpage, smrIB); + + if( (smrIB == NULL) || (smrIB == (TUint32*)KSuperPageAddressFieldUndefined)) + { + HCR_TRACE_RETURN(KErrNotSupported); + } + + HCR_HEX_DUMP_ABS((TUint8 *)smrIB, 8*sizeof(SSmrBank) ); + SSmrBank * smrBank = (SSmrBank *) smrIB; + + while( smrBank->iBase != 0 ) + { + HCR_TRACE2("--- smrBank: 0x%08x, smrBank->iPayloadUID: 0x%08x", smrBank, smrBank->iPayloadUID); + if( smrBank->iPayloadUID == KHCRUID_SMRPayloadUID) + { + HCR_TRACE2("--- smrPhysAddr: 0x%08x, size:0x%08x", smrBank->iBase, smrBank->iSize); + NKern::ThreadEnterCS(); + + TChunkCreateInfo info; + info.iType = TChunkCreateInfo::ESharedKernelSingle; + info.iMaxSize = smrBank->iSize; + // Enable to give supervisor read only access and maximum caching at both L1 and L2. + info.iMapAttr = EMapAttrSupRo|EMapAttrCachedMax; + info.iOwnsMemory = EFalse; + info.iDestroyedDfc = NULL; + TUint32 mapAttr; + TLinAddr chunkKernAddr; + TInt r = Kern::ChunkCreate(info, iChunk, chunkKernAddr, mapAttr); + if( r != KErrNone ) + { + HCR_TRACE1("--- Kern::ChunkCreate failed: 0x%08x", r); + NKern::ThreadLeaveCS(); + HCR_TRACE_RETURN(r); + } + + r = Kern::ChunkCommitPhysical(iChunk, BUFFER_OFFSET_ZERO, smrBank->iSize, smrBank->iBase); + if( r != KErrNone) + { + HCR_TRACE1("--- Kern::ChunkCommitPhysical failed: 0x%08x", r); + TInt r2 = Kern::ChunkClose(iChunk); + __NK_ASSERT_ALWAYS(r2!=0); + NKern::ThreadLeaveCS(); + HCR_TRACE_RETURN(r); + } + NKern::ThreadLeaveCS(); + + HCR_TRACE1("--- iChunkKernAddr: 0x%08x", chunkKernAddr); + // It should contains SMR and HCR image headers and some settings + HCR_HEX_DUMP_ABS((TUint8 *)chunkKernAddr, 1024 ); + + // Skip the SMR header, so we return the address of the first byte in the Repository + aAddr = (TAny *) (chunkKernAddr + sizeof(SSmrRomHeader)); + + HCR_TRACE_RETURN(KErrNone); + } + + ++smrBank; + } + + HCR_TRACE_RETURN(KErrNotSupported); + } + + +// -- ENTRY POINTS ------------------------------------------------------------ + + +GLDEF_C HCR::MVariant* CreateHCRVariant() + { + HCR_FUNC("CreateHCRVariant"); + + return new HCRVariant; + } diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/hcr/hcr_psl_config.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/hcr/hcr_psl_config.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,122 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file is part of the NE1_TB Variant Base Port +* Hardware Configuration Respoitory Platform Specific Layer (PSL) +* +*/ + + +/** +@file hcr_psl_config.h +File provides NE1 base port configuration for HCR service. It represents a +wrapper that brings togther all the ASSP, BSP, Driver, Service setting data +for the compiled repository. + +@internalTechnology +*/ + + + +// -- HCR INCLUDES ------------------------------------------------------------ + +#include + +#include "hcr_hai.h" +#include "hcr_uids.h" + +using namespace HCR; + + + +// -- HCR BSP SETTING INCLUDES ------------------------------------------------ + +// Includes for setting published by base port ASSP/SOC interconnections +#include "../../naviengine_assp/hcr/hcr_psl_config_assp_inc.inl" +#include "hcr_psl_config_mha_inc.inl" + +// Includes for MHA Hardware Service internal configuration settings +// e.g. #include "../hws/hcr_psl_config_hsw_inc.inl" +#include "../../naviengine_assp/csi/hcr_psl_config_csi_inc.inl" + +// Includes for Physical Device Driver internal configuration settings +// e.g. #include "../hws/hcr_psl_config_pdd_inc.inl" + + + +// -- HCR BSP LARGE SETTING DATA (LSD) VALUES --------------------------------- + +// Includes for setting published by base port ASSP/SOC interconnections +#include "../../naviengine_assp/hcr/hcr_psl_config_assp_lsd.inl" +#include "hcr_psl_config_mha_lsd.inl" + +// Includes for MHA Hardware Service internal configuration settings +// e.g. #include "../hws/hcr_psl_config_hsw_lsd.inl" + +// Includes for Physical Device Driver internal configuration settings +// e.g. #include "../pdd/hcr_psl_config_pdd_lsd.inl" + + + + +// -- HCR BSP SETTINGS LIST --------------------------------------------------- + +SSettingC gSettingsList[] = + { + +// Includes for setting published by base port ASSP/SOC interconnections + +// const HCR::TCategoryUid KHcrCat_MHA_HWBASE = 0x20029482; //< HCR Category for MHA ASSP Hardware Block Base Addresses +// const HCR::TCategoryUid KHcrCat_MHA_DMA = 0x20029483; //< HCR Category for MHA ASSP DMA EndPoints +#include "../../naviengine_assp/hcr/hcr_psl_config_assp.inl" +, +//const HCR::TCategoryUid KHcrCat_MHA_Interrupt = 0x20029484; //< HCR Category for MHA SoC Interrupt Source IDs +//const HCR::TCategoryUid KHcrCat_MHA_GPIO = 0x20029485; //< HCR Category for MHA SoC GPIO Pin IDs +//const HCR::TCategoryUid KHcrCat_MHA_I2S = 0x20029486; //< HCR Category for MHA SoC I2S Bus Channels +//const HCR::TCategoryUid KHcrCat_MHA_I2C = 0x20029487; //< HCR Category for MHA SoC I2C Bus IDs +//const HCR::TCategoryUid KHcrCat_MHA_SPICSI = 0x20029488; //< HCR Category for MHA SoC SPI/CSI Bus Channels +#include "hcr_psl_config_mha.inl" +, + +// Includes for MHA Hardware Service internal configuration settings +// e.g. #include "../hws/hcr_psl_config_hsw.inl" +// , +// Includes for CSI Device Driver internal configuration settings +#include "../../naviengine_assp/csi/hcr_psl_config_csi.inl" +, + +// Includes for Physical Device Driver internal configuration settings +// e.g. #include "../pdd/hcr_psl_config_mypdd.inl" +// , + + HCR_LAST_SETTING + }; + + +SRepositoryBase gHeader = + { + HCR_FINGER_PRINT, + EReposCompiled, + KRepositoryFirstVersion, + EReposReadOnly, + HCR_SETTING_COUNT(gSettingsList) + }; + + +GLDEF_C SRepositoryCompiled gRepository = + { + &gHeader, + gSettingsList + }; + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/hcr/hcr_psl_config_mha.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/hcr/hcr_psl_config_mha.inl Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,245 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file is part of the NE1_TB Variant Base Port +* Hardware Configuration Respoitory compiled repository in-line cpp. +* +*/ + + +/** +@file hcr_psl_config_mha.inl +File provides setting definitions for the MHA setting values applicable to the +NEC NaviEngine base port. These definitions also contain the setting value where +the setting value is no larger than a 32-bit integer. The values for +larger settings can be found in the peer file hcr_psl_config_mha_lsd.inl. + +@internalTechnology +*/ + + +#ifndef HCR_PSL_CONFIG_MHA_INL +#define HCR_PSL_CONFIG_MHA_INL + + +// SSettingC gSettingsList[] = +// { +// + + +/** +HCR Settings identifing the assignment of Interrrupt lines. + +These element keys are used along with the KHcrCat_MHA_Interrupt category UID +to identify and read the HCR setting. +*/ + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_ExBus}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(32)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_I2C}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(33)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_CSI0}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntCsi0)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_CSI1}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntCsi1)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_Timer0}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntIdOstMatchMsTimer)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_Timer1}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntId1stMatchMsTimer)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_Timer2}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntId2stMatchMsTimer)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_Timer3}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntId3stMatchMsTimer)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_Timer4}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntId4stMatchMsTimer)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_Timer5}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntId5stMatchMsTimer)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PWM}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(42)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_SD0}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EIntSd0)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_SD1}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EIntSd1)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_CF}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(45)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_NAND}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EIntNandCtrl)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_MIF}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(47)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DTV}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(48)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_SGX}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(49)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DISP0}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EIntDisp0)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DISP1}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(51)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DISP2}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(52)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_Video}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(53)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_SPDIF0}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(54)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_SPDIF1}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(55)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_I2S0}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntI2S0)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_I2S1}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(57)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_I2S2}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(58)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_I2S3}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(59)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_APB}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(60)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_AHB0}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(61)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_AHB1}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(62)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_AHB2}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(63)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_AXI}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(64)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PCIint}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EIntPciInt)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PCIserrb}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EIntPciSErrB)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PCIperrb}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EIntPciPErrB)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PCIExInt}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(68)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PCIExSerrb}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(69)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PCIExPerrb}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(70)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_USBHintA}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EIntUsbHIntA)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_USBHintB}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EIntUsbHIntB)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_USBHsmi}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EIntUsbHSmi)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_USBHpme}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(EIntUsbHPme)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_ATA6}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(75)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DMAC32_0end}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntDMAC32_0_End)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DMAC32_0err}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntDMAC32_0_End)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DMAC32_1end}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntDMAC32_1_End)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DMAC32_1err}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntDMAC32_1_Err)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DMAC32_2end}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntDMAC32_2_End)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DMAC32_2err}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntDMAC32_2_Err)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DMAC32_3end}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntDMAC32_3_End)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DMAC32_3err}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntDMAC32_3_Err)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DMAC32_4end}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntDMAC32_4_End)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DMAC32_4err}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntDMAC32_4_Err)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_UART0}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntIdUart0)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_UART1}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntIdUart1)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_UART2}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntIdUart2)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_UART3}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(89)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_UART4}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(90)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_UART5}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(91)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_UART6}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(92)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_UART7}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(93)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_GPIO}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntIdGpio)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_eWDT}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntDMAC64_End)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_SATA}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntDMAC64_Err)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DMACaxi_End}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(97)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DMACaxi_Err}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(98)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PMUIRG0}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(100)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PMUIRG1}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(101)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PMUIRG2}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(102)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PMUIRG3}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(103)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PMUIRG4}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(104)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PMUIRG5}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(105)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PMUIRG6}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(106)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PMUIRG7}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(107)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PMUIRG8}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(108)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PMUIRG9}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(109)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PMUIRG10}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(110)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PMUIRG11}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(111)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_COMMRX0}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(112)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_COMMRX1}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(113)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_COMMRX2}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(114)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_COMMRX3}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(115)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_COMMTX0}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(116)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_COMMTX1}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(117)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_COMMTX2}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(118)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_COMMTX3}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(119)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PWRCTLO0}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(120)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PWRCTLO1}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(121)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PWRCTLO2}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(122)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_PWRCTLO3}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(123)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DMACexbus_End}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntDMAExBus_End)}}}, + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_DMACexbus_Err}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(KIntDMAExBus_Err)}}}, + + { { { KHcrCat_MHA_Interrupt, KHcrKey_Interrupt_AHBbridge3}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(126)}}}, + + +/** +HCR Settings identifing the GPIO pin assignments. + +These element keys are used along with the KHcrCat_MHA_GPIO category UID +to identify and read the HCR setting. +*/ + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_UART1_DSR}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(8)}}}, + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_UART1_DTR}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(9)}}}, + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_UART1_DCD}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(10)}}}, + + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_CKERST}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(11)}}}, + + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_CSI_CS42L51}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(12)}}}, + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_CSIa}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(13)}}}, + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_CSIb}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(14)}}}, + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_CSIc}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(15)}}}, + + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_PCIa}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(18)}}}, + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_PCIb}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(17)}}}, + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_PCIc}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(16)}}}, + + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_RGB}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(20)}}}, + + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_eTRON}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(21)}}}, + + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_LCDl}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(22)}}}, + + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_RTC}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(23)}}}, + + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_LINT20}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(24)}}}, + + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_AUDIO_RESET}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(25)}}}, + + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_SWb0}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(27)}}}, + { { {KHcrCat_MHA_GPIO, KHcrKey_GpioPin_SWb1}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(28)}}}, + + +/** +HCR Settings identifing the I2S Bus Channels. + +These element keys are used along with the KHcrCat_MHA_I2S category UID +to identify and read the HCR setting. +*/ + + { { {KHcrCat_MHA_I2S, KHcrKey_I2S_CS42L51}, ETypeInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(0)}}}, + { { {KHcrCat_MHA_I2S, KHcrKey_I2S_Reserved1}, ETypeUndefined, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(0xFFFFFFFF)}}}, + { { {KHcrCat_MHA_I2S, KHcrKey_I2S_Reserved2}, ETypeUndefined, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(0xFFFFFFFF)}}}, + { { {KHcrCat_MHA_I2S, KHcrKey_I2S_Reserved3}, ETypeUndefined, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(0xFFFFFFFF)}}}, + + +/** +HCR Settings identifing the I2C Bus IDs. + +These element keys are used along with the KHcrCat_MHA_I2C category UID +to identify and read the HCR setting. +*/ + + { { {KHcrCat_MHA_I2C, KHcrKey_I2C_ReservedA}, ETypeUndefined, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(0xFFFFFFFF)}}}, + { { {KHcrCat_MHA_I2C, KHcrKey_I2C_ReservedB}, ETypeUndefined, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(0xFFFFFFFF)}}}, + + +/** +HCR Settings identifing the SPI/CSI Bus Channels. + +These element keys are used along with the KHcrCat_MHA_SPI_CSI category UID +to identify and read the HCR setting. +*/ + { { {KHcrCat_MHA_SPICSI, KHcrKey_CSI_CS42L51}, ETypeUInt32, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(0x0010000C)}}}, + { { {KHcrCat_MHA_SPICSI, KHcrKey_CSI_ReservedB}, ETypeUndefined, HCR_FLAGS_NONE, HCR_LEN_NA}, { {HCR_WVALUE(0xFFFFFFFF)}}} + + + +// +// Last entry must not end in a ',' as it is present in the enclosing file. +// }; + + +#endif // HCR_PSL_CONFIG_MHA_INL + + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/hcr/hcr_psl_config_mha_inc.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/hcr/hcr_psl_config_mha_inc.inl Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file is part of the NE1_TB Variant Base Port +* Hardware Configuration Respoitory compiled repository in-line cpp. +* +*/ + + +/** +@file hcr_psl_config_mha_inc.inl +File includes the headers needed to compile the MHA settings and their values +as held in the two other INL files: hcr_psl_config_assp.inl +and hcr_psl_config_assp_lsd.inl. These three files must compile cleanly +in the main hcr_psl_config.cpp file which includes the. + +@internalTechnology +*/ + + +#ifndef HCR_PSL_CONFIG_MHA_INC_INL +#define HCR_PSL_CONFIG_MHA_INC_INL + + +#include + +#include + + +#endif // HCR_PSL_CONFIG_MHA_INC_INL + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/hcr/hcr_psl_config_mha_lsd.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/hcr/hcr_psl_config_mha_lsd.inl Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file is part of the NE1_TB Variant Base Port +* Hardware Configuration Respoitory compiled repository in-line cpp. +* +*/ + + +/** +@file hcr_psl_config_mha_lsd.inl +File provides large setting value definitions for the MHA setting values +applicable to the NEC NaviEngine base port. + +@internalTechnology +*/ + + +#ifndef HCR_PSL_CONFIG_MHA_LSD_INL +#define HCR_PSL_CONFIG_MHA_LSD_INL + + +// No large setting values defined for MHA settings at present. + + +#endif // HCR_PSL_CONFIG_MHA_LSD_INL + + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/hcr/hcrconfig.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/hcr/hcrconfig.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,105 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file is part of the NE1_TB Variant Base Port +* Hardware Configuration Respoitory Published Setting IDs header. +* +*/ + + + +/** +@file hcrconfig_assp.h +File provides const uint definitions for the published set of HCR settings +identifiers applicable to the NEC NaviEngine base port. +The settings defined in the HCR are examples for "device configuration" for +the platform and not an exhustive list. The HCR is not intended to hold +"feature configuration" which if varied would required significant code +changes in the hardware consumer component. + +=============================================================== + ____ _ _ +| _ \ _ __ ___ | |_ ___ | |_ _ _ _ __ ___ +| |_) | '__/ _ \| __/ _ \| __| | | | '_ \ / _ \ +| __/| | | (_) | || (_) | |_| |_| | |_) | __/ +|_| |_| \___/ \__\___/ \__|\__, | .__/ \___| + |___/|_| + +This API and component are in an early release form. As such +this component, it's API/HAI interfaces and internal design +are not fixed and may be updated/changed at any time before +final release. + +=============================================================== + +@publishedPartner +@prototype +*/ + +#ifndef HCR_CONFIG_H +#define HCR_CONFIG_H + + + +// -- INCLUDES ---------------------------------------------------------------- + +#include + + + +// -- CATEGORY UIDs ----------------------------------------------------------- + +const HCR::TCategoryUid KHcrCat_MHA_Base = 0x20029482; //< Lowest UID in SymSign allocated UID range for HCR MHA Settings +const HCR::TCategoryUid KHcrCat_MHA_Max = 0x20029491; //< Highest UID in SymSign allocated UID range for HCR MHA Settings + +const HCR::TCategoryUid KHcrCat_MHA_HWBASE = 0x20029482; //< HCR Category for MHA ASSP Hardware Block Base Addresses +const HCR::TCategoryUid KHcrCat_MHA_DMA = 0x20029483; //< HCR Category for MHA ASSP DMA EndPoints +const HCR::TCategoryUid KHcrCat_MHA_Interrupt = 0x20029484; //< HCR Category for MHA SoC Interrupt Source IDs +const HCR::TCategoryUid KHcrCat_MHA_GPIO = 0x20029485; //< HCR Category for MHA SoC GPIO Pin IDs +const HCR::TCategoryUid KHcrCat_MHA_I2S = 0x20029486; //< HCR Category for MHA SoC I2S Bus Channels +const HCR::TCategoryUid KHcrCat_MHA_I2C = 0x20029487; //< HCR Category for MHA SoC I2C Bus IDs +const HCR::TCategoryUid KHcrCat_MHA_SPICSI = 0x20029488; //< HCR Category for MHA SoC SPI/CSI Bus Channels + + + +const HCR::TCategoryUid KHcrCat_HWServ_Base = 0x20029D1D; //< Lowest UID in SymSign allocated UID range for HCR Hardware Service provider configuration +const HCR::TCategoryUid KHcrCat_HWServ_Max = 0x20029D24; //< Highest UID in SymSign allocated UID range for HCR Hardware Service provider configuration + +const HCR::TCategoryUid KHcrCat_HWServ_CSI = 0x20029D1D; //< Private HCR UID allocated for CSI configuration + + + +const HCR::TCategoryUid KHcrCat_DevDrvier_Base = 0x20029D25; //< Lowest UID in SymSign allocated UID range for HCR NE1 +const HCR::TCategoryUid KHcrCat_DevDriver_Max = 0x20029D2C; //< Highest UID in SymSign allocated UID range for HCR NE1 + + + +// -- ASSP SETTING KEYS ------------------------------------------------------- + +#include + + + + +// -- MHA SETTING KEYS -------------------------------------------------------- + +#include + + + +#endif // HCR_CONFIG_H + + + + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/hcr/hcrconfig_mha.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/hcr/hcrconfig_mha.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,254 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file is part of the NE1_TB Variant Base Port +* Hardware Configuration Respoitory Published Setting IDs header. +* +*/ + + + +/** +@file hcrconfig_assp.h +File provides definitions for the published set of HCR settings +identifiers applicable to the MHA Services on the NEC NaviEngine +base port. + +@publishedPartner +@prototype +*/ + +#ifndef HCRCONFIG_MHA_H +#define HCRCONFIG_MHA_H + + + +// -- INCLUDES ---------------------------------------------------------------- + +#include + + + +// -- CATEGORY UIDs ----------------------------------------------------------- + + + +// -- KEYS -------------------------------------------------------------------- + +/** +HCR Settings identifing the assignment of Interrrupt lines. + +These element keys are used along with the KHcrCat_MHA_Interrupt category UID +to identify and read the HCR setting. +*/ +#define INT_SRC 0x00010000 +const HCR::TElementId KHcrKey_Interrupt_ExBus = INT_SRC + 11; //< + +const HCR::TElementId KHcrKey_Interrupt_I2C = INT_SRC + 12; //< + +const HCR::TElementId KHcrKey_Interrupt_CSI0 = INT_SRC + 13; //< +const HCR::TElementId KHcrKey_Interrupt_CSI1 = INT_SRC + 14; //< + +const HCR::TElementId KHcrKey_Interrupt_Timer0 = INT_SRC + 21; //< SoC Timer0 interrupt +const HCR::TElementId KHcrKey_Interrupt_Timer1 = INT_SRC + 22; //< SoC Timer1 interrupt +const HCR::TElementId KHcrKey_Interrupt_Timer2 = INT_SRC + 23; //< SoC Timer2 interrupt +const HCR::TElementId KHcrKey_Interrupt_Timer3 = INT_SRC + 24; //< SoC Timer3 interrupt +const HCR::TElementId KHcrKey_Interrupt_Timer4 = INT_SRC + 25; //< SoC Timer4 interrupt +const HCR::TElementId KHcrKey_Interrupt_Timer5 = INT_SRC + 26; //< SoC Timer5 interrupt + +const HCR::TElementId KHcrKey_Interrupt_PWM = INT_SRC + 31; //< + +const HCR::TElementId KHcrKey_Interrupt_SD0 = INT_SRC + 32; //< SD #0 : OXMNIRQ +const HCR::TElementId KHcrKey_Interrupt_SD1 = INT_SRC + 33; //< SD #1 : OXASIOIRQ //SDIO + +const HCR::TElementId KHcrKey_Interrupt_CF = INT_SRC + 41; //< +const HCR::TElementId KHcrKey_Interrupt_NAND = INT_SRC + 42; //< Nand Controller +const HCR::TElementId KHcrKey_Interrupt_MIF = INT_SRC + 43; //< +const HCR::TElementId KHcrKey_Interrupt_DTV = INT_SRC + 44; //< +const HCR::TElementId KHcrKey_Interrupt_SGX = INT_SRC + 45; //< + +const HCR::TElementId KHcrKey_Interrupt_DISP0 = INT_SRC + 51; //< DISP 0 +const HCR::TElementId KHcrKey_Interrupt_DISP1 = INT_SRC + 52; //< +const HCR::TElementId KHcrKey_Interrupt_DISP2 = INT_SRC + 53; //< + +const HCR::TElementId KHcrKey_Interrupt_Video = INT_SRC + 61; //< +const HCR::TElementId KHcrKey_Interrupt_SPDIF0 = INT_SRC + 62; //< +const HCR::TElementId KHcrKey_Interrupt_SPDIF1 = INT_SRC + 63; //< + +const HCR::TElementId KHcrKey_Interrupt_I2S0 = INT_SRC + 71; //< I2S 0 Interrupts +const HCR::TElementId KHcrKey_Interrupt_I2S1 = INT_SRC + 72; //< +const HCR::TElementId KHcrKey_Interrupt_I2S2 = INT_SRC + 73; //< +const HCR::TElementId KHcrKey_Interrupt_I2S3 = INT_SRC + 74; //< + +const HCR::TElementId KHcrKey_Interrupt_APB = INT_SRC + 81; //< +const HCR::TElementId KHcrKey_Interrupt_AHB0 = INT_SRC + 82; //< +const HCR::TElementId KHcrKey_Interrupt_AHB1 = INT_SRC + 83; //< +const HCR::TElementId KHcrKey_Interrupt_AHB2 = INT_SRC + 84; //< + +const HCR::TElementId KHcrKey_Interrupt_AXI = INT_SRC + 91; //< + +const HCR::TElementId KHcrKey_Interrupt_PCIint = INT_SRC + 101; //< PCI Int +const HCR::TElementId KHcrKey_Interrupt_PCIserrb = INT_SRC + 102; //< PCI Systerm Error +const HCR::TElementId KHcrKey_Interrupt_PCIperrb = INT_SRC + 103; //< PCI Parity Error +const HCR::TElementId KHcrKey_Interrupt_PCIExInt = INT_SRC + 104; //< +const HCR::TElementId KHcrKey_Interrupt_PCIExSerrb = INT_SRC + 105; //< +const HCR::TElementId KHcrKey_Interrupt_PCIExPerrb = INT_SRC + 106; //< + +const HCR::TElementId KHcrKey_Interrupt_USBHintA = INT_SRC + 111; //< USB Host Int A +const HCR::TElementId KHcrKey_Interrupt_USBHintB = INT_SRC + 112; //< USB Host Int B +const HCR::TElementId KHcrKey_Interrupt_USBHsmi = INT_SRC + 113; //< USB Host System Management Interrupt +const HCR::TElementId KHcrKey_Interrupt_USBHpme = INT_SRC + 114; //< USB Host Power Management Event + +const HCR::TElementId KHcrKey_Interrupt_ATA6 = INT_SRC + 121; //< + +const HCR::TElementId KHcrKey_Interrupt_DMAC32_0end = INT_SRC + 131; //< +const HCR::TElementId KHcrKey_Interrupt_DMAC32_0err = INT_SRC + 132; //< +const HCR::TElementId KHcrKey_Interrupt_DMAC32_1end = INT_SRC + 133; //< +const HCR::TElementId KHcrKey_Interrupt_DMAC32_1err = INT_SRC + 134; //< +const HCR::TElementId KHcrKey_Interrupt_DMAC32_2end = INT_SRC + 135; //< +const HCR::TElementId KHcrKey_Interrupt_DMAC32_2err = INT_SRC + 136; //< +const HCR::TElementId KHcrKey_Interrupt_DMAC32_3end = INT_SRC + 137; //< +const HCR::TElementId KHcrKey_Interrupt_DMAC32_3err = INT_SRC + 138; //< +const HCR::TElementId KHcrKey_Interrupt_DMAC32_4end = INT_SRC + 139; //< +const HCR::TElementId KHcrKey_Interrupt_DMAC32_4err = INT_SRC + 140; //< + +const HCR::TElementId KHcrKey_Interrupt_UART0 = INT_SRC + 151; //< SoC Uart #0 +const HCR::TElementId KHcrKey_Interrupt_UART1 = INT_SRC + 152; //< SoC Uart #1 +const HCR::TElementId KHcrKey_Interrupt_UART2 = INT_SRC + 153; //< SoC Uart #2 +const HCR::TElementId KHcrKey_Interrupt_UART3 = INT_SRC + 154; //< +const HCR::TElementId KHcrKey_Interrupt_UART4 = INT_SRC + 155; //< +const HCR::TElementId KHcrKey_Interrupt_UART5 = INT_SRC + 156; //< +const HCR::TElementId KHcrKey_Interrupt_UART6 = INT_SRC + 157; //< +const HCR::TElementId KHcrKey_Interrupt_UART7 = INT_SRC + 158; //< + +const HCR::TElementId KHcrKey_Interrupt_GPIO = INT_SRC + 161; //< +const HCR::TElementId KHcrKey_Interrupt_eWDT = INT_SRC + 162; //< +const HCR::TElementId KHcrKey_Interrupt_SATA = INT_SRC + 163; //< + +const HCR::TElementId KHcrKey_Interrupt_DMACaxi_End = INT_SRC + 171; //< +const HCR::TElementId KHcrKey_Interrupt_DMACaxi_Err = INT_SRC + 172; //< + +const HCR::TElementId KHcrKey_Interrupt_PMUIRG0 = INT_SRC + 181; //< +const HCR::TElementId KHcrKey_Interrupt_PMUIRG1 = INT_SRC + 182; //< +const HCR::TElementId KHcrKey_Interrupt_PMUIRG2 = INT_SRC + 183; //< +const HCR::TElementId KHcrKey_Interrupt_PMUIRG3 = INT_SRC + 184; //< +const HCR::TElementId KHcrKey_Interrupt_PMUIRG4 = INT_SRC + 185; //< +const HCR::TElementId KHcrKey_Interrupt_PMUIRG5 = INT_SRC + 186; //< +const HCR::TElementId KHcrKey_Interrupt_PMUIRG6 = INT_SRC + 187; //< +const HCR::TElementId KHcrKey_Interrupt_PMUIRG7 = INT_SRC + 188; //< +const HCR::TElementId KHcrKey_Interrupt_PMUIRG8 = INT_SRC + 189; //< +const HCR::TElementId KHcrKey_Interrupt_PMUIRG9 = INT_SRC + 190; //< +const HCR::TElementId KHcrKey_Interrupt_PMUIRG10 = INT_SRC + 191; //< +const HCR::TElementId KHcrKey_Interrupt_PMUIRG11 = INT_SRC + 192; //< + +const HCR::TElementId KHcrKey_Interrupt_COMMRX0 = INT_SRC + 201; //< +const HCR::TElementId KHcrKey_Interrupt_COMMRX1 = INT_SRC + 202; //< +const HCR::TElementId KHcrKey_Interrupt_COMMRX2 = INT_SRC + 203; //< +const HCR::TElementId KHcrKey_Interrupt_COMMRX3 = INT_SRC + 204; //< +const HCR::TElementId KHcrKey_Interrupt_COMMTX0 = INT_SRC + 205; //< +const HCR::TElementId KHcrKey_Interrupt_COMMTX1 = INT_SRC + 206; //< +const HCR::TElementId KHcrKey_Interrupt_COMMTX2 = INT_SRC + 207; //< +const HCR::TElementId KHcrKey_Interrupt_COMMTX3 = INT_SRC + 208; //< + +const HCR::TElementId KHcrKey_Interrupt_PWRCTLO0 = INT_SRC + 211; //< +const HCR::TElementId KHcrKey_Interrupt_PWRCTLO1 = INT_SRC + 212; //< +const HCR::TElementId KHcrKey_Interrupt_PWRCTLO2 = INT_SRC + 213; //< +const HCR::TElementId KHcrKey_Interrupt_PWRCTLO3 = INT_SRC + 214; //< + +const HCR::TElementId KHcrKey_Interrupt_DMACexbus_End = INT_SRC + 221; //< +const HCR::TElementId KHcrKey_Interrupt_DMACexbus_Err = INT_SRC + 222; //< +const HCR::TElementId KHcrKey_Interrupt_AHBbridge3 = INT_SRC + 223; //< + +#undef INT_SRC + + +/** +HCR Settings identifing the GPIO pin assignments. + +These element keys are used along with the KHcrCat_MHA_GPIO category UID +to identify and read the HCR setting. +*/ +#define GPIO_PIN 0x00020000 +const HCR::TElementId KHcrKey_GpioPin_UART1_DSR = GPIO_PIN + 11; //< Serial DSR on RGB board +const HCR::TElementId KHcrKey_GpioPin_UART1_DTR = GPIO_PIN + 12; //< Serial DTR on RGB board +const HCR::TElementId KHcrKey_GpioPin_UART1_DCD = GPIO_PIN + 13; //< Serial DCD on RGB board + +const HCR::TElementId KHcrKey_GpioPin_CKERST = GPIO_PIN + 21; //< Line to FPGA + +const HCR::TElementId KHcrKey_GpioPin_CSI_CS42L51 = GPIO_PIN + 22; //< Line to CS42L51 +const HCR::TElementId KHcrKey_GpioPin_CSIa = GPIO_PIN + 23; //< Line to Test Pin Header +const HCR::TElementId KHcrKey_GpioPin_CSIb = GPIO_PIN + 24; //< Line to Test Pin Header +const HCR::TElementId KHcrKey_GpioPin_CSIc = GPIO_PIN + 25; //< Line to Test Pin Header + +const HCR::TElementId KHcrKey_GpioPin_PCIa = GPIO_PIN + 26; //< ExtBus Connector +const HCR::TElementId KHcrKey_GpioPin_PCIb = GPIO_PIN + 27; //< ExtBus Connector +const HCR::TElementId KHcrKey_GpioPin_PCIc = GPIO_PIN + 28; //< ExtBus Connector + +const HCR::TElementId KHcrKey_GpioPin_RGB = GPIO_PIN + 41; //< Line to FPGA + +const HCR::TElementId KHcrKey_GpioPin_eTRON = GPIO_PIN + 42; //< Line to FPGA + +const HCR::TElementId KHcrKey_GpioPin_LCDl = GPIO_PIN + 43; //< Line to FPGA + +const HCR::TElementId KHcrKey_GpioPin_RTC = GPIO_PIN + 44; //< Line to FPGA + +const HCR::TElementId KHcrKey_GpioPin_LINT20 = GPIO_PIN + 45; //< Line to FPGA + +const HCR::TElementId KHcrKey_GpioPin_AUDIO_RESET = GPIO_PIN + 46; //< CS42L51 codec reset line + +const HCR::TElementId KHcrKey_GpioPin_SWb0 = GPIO_PIN + 61; //< Line to FPGA +const HCR::TElementId KHcrKey_GpioPin_SWb1 = GPIO_PIN + 62; //< Line to FPGA +#undef GPIO_PIN + + +/** +HCR Settings identifing the I2S Bus Channels. + +These element keys are used along with the KHcrCat_MHA_I2S category UID +to identify and read the HCR setting. +*/ +#define I2S_CHAN 0x00030000 +const HCR::TElementId KHcrKey_I2S_CS42L51 = I2S_CHAN + 11; //< Channel used with the Audio Codec +const HCR::TElementId KHcrKey_I2S_Reserved1 = I2S_CHAN + 12; //< +const HCR::TElementId KHcrKey_I2S_Reserved2 = I2S_CHAN + 13; //< +const HCR::TElementId KHcrKey_I2S_Reserved3 = I2S_CHAN + 14; //< +#undef I2S_CHAN + + +/** +HCR Settings identifing the I2C Bus IDs. + +These element keys are used along with the KHcrCat_MHA_I2C category UID +to identify and read the HCR setting. +*/ +#define I2C_BUS 0x00040000 +const HCR::TElementId KHcrKey_I2C_ReservedA = I2C_BUS + 11; //< +const HCR::TElementId KHcrKey_I2C_ReservedB = I2C_BUS + 12; //< +#undef I2S_BUS + + +/** +HCR Settings identifing the SPI/CSI Bus Channels. + +These element keys are used along with the KHcrCat_MHA_SPI_CSI category UID +to identify and read the HCR setting. +*/ +#define CSI_CHAN 0x00050000 +const HCR::TElementId KHcrKey_CSI_CS42L51 = CSI_CHAN + 11; //< +const HCR::TElementId KHcrKey_CSI_ReservedB = CSI_CHAN + 12; //< +#undef CSI_CHAN + + +#endif HCRCONFIG_MHA_H + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/i2s.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/i2s.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/i2s.mmp +* +*/ + + + +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "kernel/kern_ext.mmh" + +USERINCLUDE ../naviengine_assp +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + +sourcepath ../naviengine_assp/i2s +source i2s_pil.cpp + +sourcepath ../naviengine_assp/i2s +source i2s_psl.cpp + +epocallowdlldata + +target VariantTarget(i2s,dll) +targettype kext +linkas i2s.dll + +deffile ../naviengine_assp/~/ei2s.def + +capability all + +romtarget i2s.dll + +//noexportlibrary + +uid 0x1000008d 0x100039ea +VENDORID 0x70000001 + +SMPSAFE + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/inc/cs42l51.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/inc/cs42l51.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,237 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\inc\cs42l51.h +* +*/ + + + +#ifndef CS42L51_H_ +#define CS42L51_H_ +#include + + +const TUint KMaxAttempts = 2000; // Number of maximum attempts in operations +const TInt8 KCodecWriteCommand = 0x94; // value of the first byte to be sent in each write request on CSI bus. + +const TInt KCodecResetPin = 25; // GPIO pin 25 works as AUDIO_RESET +const TInt KCodecCSPin = 12; // GPIO pin 12 works as CS. + +const TUint KHwCS42L51ChipID = 0x01; // Chip I.D. and Revision Register (Address 01h) (Read Only) +const TUint KHwCS42L51PwrCtrl = 0x02; // Power Control 1 +const TUint KHtCS42L51PwrCtrl_PDN_ALL = 0x7f; // Power Down ALL (bit 7-reserved) +const TUint KHtCS42L51PwrCtrl_PDN_DACB = 1<<6; // Power Down DACB +const TUint KHtCS42L51PwrCtrl_PDN_DACA = 1<<5; // Power Down DACA +const TUint KHtCS42L51PwrCtrl_PDN_PGAB = 1<<4; // Power Down PGAB +const TUint KHtCS42L51PwrCtrl_PDN_PGAA = 1<<3; // Power Down PGAA +const TUint KHtCS42L51PwrCtrl_PDN_ADCB = 1<<2; // Power Down ADCB +const TUint KHtCS42L51PwrCtrl_PDN_ADCA = 1<<1; // Power Down ADCA +const TUint KHtCS42L51PwrCtrl_PDN = 1<<0; // Power Down + +const TUint KHwCS42L51MicPwrSpeed = 0x03; // MIC Power Control & Speed Control +const TUint KHtCS42L51MicPwrSpeed_AUTO = 1<<7; // Auto-Detect Speed Mode +const TUint KHtCS42L51MicPwrSpeed_3ST_SP = 1<<4; // Tri-State Serial Port Interface +const TUint KHtCS42L51MicPwrSpeed_PDN_MICB = 1<<3; // Power Down MICB +const TUint KHtCS42L51MicPwrSpeed_PDN_MICA = 1<<2; // Power Down MICA +const TUint KHtCS42L51MicPwrSpeed_PDN_MICBIAS = 1<<1; // MCLK Divide By 2 +const TUint KHtCS42L51MicPwrSpeed_MCLKDIV2 = 1<<0; // MCLK Divide By 2 + +const TUint KHsCS42L51MicPwrSpeed = 5; // Speed shift (bits[6:5]) +const TUint KHCS42L51MicPwrSpeed_SpeedQSM = 3; // Quarter-Speed Mode (QSM) - 4 to 12.5 kHz sample rates +const TUint KHCS42L51MicPwrSpeed_SpeedHSM = 2; // Half-Speed Mode (HSM) - 12.5 to 25 kHz sample rates +const TUint KHCS42L51MicPwrSpeed_SpeedSSM = 1; // Single-Speed Mode (SSM) - 4 to 50 kHz sample rates +const TUint KHCS42L51MicPwrSpeed_SpeedDSM = 0; // Double-Speed Mode (DSM) - 50 to 100 kHz sample rates + +const TUint KHwCS42L51Ctrl = 0x04; // Interface Control +const TUint KHtCS42L51Ctrl_SDOUT_SDIN = 1<<7; // SDOUT to SDIN Loopback +const TUint KHtCS42L51Ctrl_MS = 1<<6; // Master/Slave Mode +const TUint KHtCS42L51Ctrl_ADC_I2S = 1<<2; // ADC I2S or Left-Justified +const TUint KHtCS42L51Ctrl_DIGMIX = 1<<1; // Digital Mix +const TUint KHtCS42L51Ctrl_MICMIX = 1<<0; // Mic Mix + +const TUint KHsCS42L51CtrlFormat = 3; // DAC Digital Interface Format shift(DAC_DIF[5:3]) +const TUint KHCS42L51CtrlLeftJustifiedUpto24bit = 0; +const TUint KHCS42L51CtrlI2sUpto24bit = 1; +const TUint KHCS42L51CtrlRightJustifiedUpto24bit = 2; +const TUint KHCS42L51CtrlRightJustifiedUpto20bit = 3; +const TUint KHCS42L51CtrlRightJustifiedUpto18bit = 4; +const TUint KHCS42L51CtrlRightJustifiedUpto16bit = 5; + +const TUint KHwCS42L51MicCtrl = 0x05; // MIC Control +const TUint KHtCS42L51MicCtrl_ADC_SNGVOL = 1<<7; // ADC Single Volume Control +const TUint KHtCS42L51MicCtrl_ADCB_DBOOST = 1<<6; // ADCB 20 dB Digital Boost +const TUint KHtCS42L51MicCtrl_ADCA_DBOOST = 1<<5; // ADCA 20 dB Digital Boost +const TUint KHtCS42L51MicCtrl_MICBIAS_SEL = 1<<4; // MIC Bias Select +const TUint KHtCS42L51MicCtrl_MICB_BOOST = 1<<1; // MIC B Preamplifier Boost +const TUint KHtCS42L51MicCtrl_MICA_BOOST = 1<<0; // MIC A Preamplifier Boost +const TUint KHsCS42L51MicCtrl_MICBIAS = 2; // MIC Bias Level shift (0-3) [3:2] + +const TUint KHwCS42L51ADCCtrl = 0x06; // ADC Control +const TUint KHtCS42L51ADCCtrl_ADCB_HPFEN = 1<<7; // ADCB High-Pass Filter Enable +const TUint KHtCS42L51ADCCtrl_ADCB_HPFRZ = 1<<6; // ADCB High-Pass Filter Freeze +const TUint KHtCS42L51ADCCtrl_ADCA_HPFEN = 1<<5; // ADCA High-Pass Filter Enable +const TUint KHtCS42L51ADCCtrl_ADCA_HPFRZ = 1<<4; // ADCA High-Pass Filter Freeze +const TUint KHtCS42L51ADCCtrl_SOFTB = 1<<3; // Soft Ramp CHB Control +const TUint KHtCS42L51ADCCtrl_ZCROSSB = 1<<2; // Zero Cross CHB Control +const TUint KHtCS42L51ADCCtrl_SOFTA = 1<<1; // Soft Ramp CHA Control +const TUint KHtCS42L51ADCCtrl_ZCROSSA = 1<<0; // Zero Cross CHA Control + +const TUint KHwCS42L51ADCInputMute = 0x07; // ADCx Input Select, Invert & Mute +const TUint KHsCS42L51ADCInputMute_AINB_MUX = 6; // ADCB Input Select Bits [7:6] +const TUint KHsCS42L51ADCInputMute_AINA_MUX = 4; // ADCA Input Select Bits [5:4] +/* +PDN_PGAx AINx_MUX[1:0] Selected Path to ADC + 0 00 AIN1x-->PGAx + 0 01 AIN2x-->PGAx + 0 10 AIN3x/MICINx-->PGAx + 0 11 AIN3x/MICINx-->Pre-Amp(+16/+32 dB Gain)-->PGAx + 1 00 AIN1x + 1 01 AIN2x + 1 10 AIN3x/MICINx + 1 11 Reserved */ +const TUint KHwCS42L51ADCInputMute_INV_ADCB = 1<<3; // ADCB Invert Signal Polarity +const TUint KHwCS42L51ADCInputMute_INV_ADCA = 1<<2; // ADCA Invert Signal Polarity +const TUint KHwCS42L51ADCInputMute_ADCB_MUTE = 1<<1; // ADCB Channel Mute +const TUint KHwCS42L51ADCInputMute_ADCA_MUTE = 1<<0; // ADCA Channel Mute + +const TUint KHwCS42L51DACOutputControl = 0x08; // DAC Output Control +const TUint KHsCS42L51DACOutputControl_HP_GAIN = 5; // Headphone Analog Gain (HP_GAIN[7:5]) +const TUint KHtCS42L51DACOutputControl_DAC_SNGVOL = 1<<4; // DAC Single Volume Control +const TUint KHtCS42L51DACOutputControl_INV_PCMB = 1<<3; // PCMB Invert Signal Polarity +const TUint KHtCS42L51DACOutputControl_INV_PCMA = 1<<2; // PCMA Invert Signal Polarity +const TUint KHtCS42L51DACOutputControl_DACB_MUTE = 1<<1; // DACB Channel Mute +const TUint KHtCS42L51DACOutputControl_DACA_MUTE = 1<<0; // DACA Channel Mute +const TUint KHtCS42L51DACOutputControl_DACAB_MUTE = 3<<0; // DACA and DACB Channel Mute + + +const TUint KHwCS42L51DACControl = 0x09; // DAC Control +const TUint KHsCS42L51DACControl_DATA_SEL = 6; // DAC Data Selection (DATA_SEL[7:6]) +/*00 - PCM Serial Port to DAC + 01 - Signal Processing Engine to DAC + 10 - ADC Serial Port to DAC + 11 - Reserved */ +const TUint KHtCS42L51DACControl_FREEZE = 1<<5; // Freeze Controls +const TUint KHtCS42L51DACControl_DEEMPH = 1<<3; // DAC De-Emphasis Control +const TUint KHtCS42L51DACControl_AMUTE = 1<<2; // Analog Output Auto MUTE +const TUint KHsCS42L51DACControl_DAC_SZC = 0; // DAC Soft Ramp and Zero Cross Control (DAC_SZC[1:0]) + +const TUint KHwCS42L51ALC_PGA_A_Control = 0x0A; // ALCA & PGAA Control +const TUint KHtCS42L51ALC_PGA_A_Control_ALC_SRDIS = 1<<7; // ALCA Soft Ramp Disable +const TUint KHtCS42L51ALC_PGA_A_Control_ALC_ZCDIS = 1<<6; // ALCA Zero Cross Disable +const TUint KHsCS42L51ALC_PGA_A_Control_PGA_VOL = 0; // PGA A Gain Control + +const TUint KHwCS42L51ALC_PGA_B_Control = 0x0B; // ALCB & PGAB Control +const TUint KHtCS42L51ALC_PGA_B_Control_ALC_SRDIS = 1<<7; // ALCB Soft Ramp Disable +const TUint KHtCS42L51ALC_PGA_B_Control_ALC_ZCDIS = 1<<6; // ALCB Zero Cross Disable +const TUint KHsCS42L51ALC_PGA_B_Control_PGA_VOL = 0; // PGA B Gain Control + +const TUint KHwCS42L51ALC_ADC_A_Attenuator = 0x0C; // ADCA Attenuator +const TUint KHwCS42L51ALC_ADC_B_Attenuator = 0x0D; // ADCB Attenuator + +const TUint KHwCS42L51ALC_ADC_A_MixVolume = 0x0E; // ADCA Mixer Volume Control +const TUint KHwCS42L51ALC_ADC_B_MixVolume = 0x0F; // ADCB Mixer Volume Control + +const TUint KHwCS42L51ALC_PCM_A_MixVolume = 0x10; // PCMA Mixer Volume Control +const TUint KHwCS42L51ALC_PCM_B_MixVolume = 0x11; // PCMB Mixer Volume Control + +// this applies to ADCx_MixVolume and PCMx_MixVolume registers.. +const TUint KHtCS42L51ALC_MixVolume_ChannelMute = 1<<7; // Channel Mute +const TUint KHmCS42L51ALC_MixVolume_VolumeMask = 0x7F; // Volume Control Mask + +const TUint KHwCS42L51ALC_Beep_FQ_Time = 0x12; // Beep Frequency & Timing Configuration +const TUint KHsCS42L51ALC_Beep_FQ = 4; // Beep Frequency (FREQ[7:4]) +const TUint KHmCS42L51ALC_Beep_FQ_Mask = 0xF0; // Beep frequency mask +const TUint KHsCS42L51ALC_Beep_Time = 0; // Beep on duration (ONTIME[3:0]) +const TUint KHmCS42L51ALC_Beep_Time_Mask = 0x0F; // Time on duration mask + +const TUint KHwCS42L51ALC_Beep_Off_Volume = 0x13; // Beep Off Time & Volume +const TUint KHsCS42L51ALC_Beep_Off = 5; // Beep off time mask +const TUint KHmCS42L51ALC_Beep_Off_Mask = 0xE0; // Beep off time mask +const TUint KHmCS42L51ALC_Beep_Volume_Mask = 0x1F; // Beep volume mask + +const TUint KHwCS42L51ALC_Beep_Conf_Tone = 0x14; // Beep Configuration & Tone Configuration +const TUint KHtCS42L51ALC_Beep_Conf_Tone_REPEAT = 1<<7; // Repeat Beep +const TUint KHtCS42L51ALC_Beep_Conf_Tone_BEEP = 1<<6; // Beep +const TUint KHtCS42L51ALC_Beep_Conf_Tone_TC_EN = 1<<0; // Tone Control Enable +const TUint KHsCS42L51ALC_Beep_Conf_Tone_TREB_CF = 3; // Treble Corner Frequency (TREB_CF[4:3]) +const TUint KHsCS42L51ALC_Beep_Conf_Tone_BASS_CF = 1; // Bass Corner Frequency (BASS_CF[2:1]) + +const TUint KHwCS42L51ALC_ToneCtrl = 0x15; // Tone Control +const TUint KHsCS42L51ALC_ToneCtrl_TREB = 4; // Treble Gain Level (TREB[7:4]) +const TUint KHmCS42L51ALC_ToneCtrl_TREB_Mask = 0xF0; // Treble Gain Level mask +const TUint KHsCS42L51ALC_ToneCtrl_BASS = 0; // Bass Gain Level (TREB[7:4]) +const TUint KHmCS42L51ALC_ToneCtrl_BASS_Mask = 0x0F; // Bass Gain Level mask + +const TUint KHwCS42L51ALC_Out_A_Volume = 0x16; // AOUTA Volume Control +const TUint KHwCS42L51ALC_Out_B_Volume = 0x17; // AOUTB Volume Control +const TUint KHbCS42L51ALC_Volume_Min = 25; // Value for ALC_Out_x for Minimum Volume + + +const TUint KHwCS42L51ALC_PCM_Mix = 0x18; // PCM Channel Mixer +const TUint KHwCS42L51ALC_Limiter_SZCD = 0x19; // Limiter Threshold SZC Disable +const TUint KHwCS42L51ALC_Limiter_Release = 0x1A; // Limiter Release Rate Register +const TUint KHwCS42L51ALC_Limiter_Attack = 0x1B; // Limiter Attack Rate Register +const TUint KHwCS42L51ALC_ALCE_Attack_Rate = 0x1C; // ALC Enable & Attack Rate +const TUint KHwCS42L51ALC_ALC_Release_Rate = 0x1D; // ALC Release Rate +const TUint KHwCS42L51ALC_ALC_Threshold = 0x1E; // ALC Threshold +const TUint KHwCS42L51ALC_NoiseGate_Misc = 0x1F; // Noise Gate Configuration & Misc +const TUint KHwCS42L51ALC_Status = 0x20; // Noise Gate Configuration & Misc +const TUint KHwCS42L51ALC_Charge_Pump_Fq = 0x21; // Charge Pump Frequency + +/** +Definiton of audio codec singleton class... +*/ +class RCS42AudioCodec + { +public: + + struct TCodecConfigData + { + TInt8 iAddress; + TInt8 iRegister; + TInt8 iData; + }; +public: + static TInt Open(RCS42AudioCodec* &aSelf); // open the reference codec + static void Close(RCS42AudioCodec* &aSelf); // close the reference to the codec + TInt SetPlayVolume(TInt aVolume); // set the Playback volume + TInt SetRecordVolume(TInt aVolume); // set the Record volume + +private: + RCS42AudioCodec(); + static TInt Create(); // create an instance of the codec + static void Destroy(); // delete an instance of the codec + TInt DoWrite(TUint16 aRegAddr, TUint16 aData); + void StartWrite(); + TInt StopWrite(); + void Write(TUint16 aRegAddr, TUint16 aData); // access codec's registers + TInt Init(); + void PowerDown(); + static RCS42AudioCodec* iSelf; + static TInt iRefCnt; + TInt iTransferStatus; + TUint8 iInterfaceCtrlVal; + TInt iResult; + +#ifdef _DEBUG + TBool iStartWriteCalled; +#endif + TConfigSpiBufV01 iHeaderBuff; + TPckgBuf iTransBuff; + TUint32 iCsiBusConfig; + }; + + +#endif /*CS42L51_H_*/ diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/inc/iolines.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/inc/iolines.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,129 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\inc\iolines.h +* Variant layer header for NE1_TBVariant Platform +* +*/ + + + +#ifndef __NE1_TBIOLINES_H__ +#define __NE1_TBIOLINES_H__ +#include +#include + +//---------------------------------------------------------------------------- +// Variant-specific constants: use #define if constant dependencies are not +// declared within this file (this breaks the dependency on other header files) +//---------------------------------------------------------------------------- + +// Examples of what goes in here include: +// +// - General-purpose I/O allocation such as +// #define KtVariantGpio32KHzClkOut KHtGpioPort1 +// #define KtVariantGpioRClkOut KHtGpioPort0 +// +// #define KmVariantPinDirectionIn Sleep 0 +// +// - Memory constants (type, geometry, wait states, etc) such as: +// #define KwVariantRom0Type TNaviEngine::ERomTypeBurst4Rom +// #define KwVariantRom0Width TNaviEngine::ERomWidth32 +// const TUint KwVariantRom0WaitNs = 150; +// const TUint KwVariantRom0PageNs = 30; +// const TUint KwVariantRom0RecoverNs = 55; +// +// - Specific Peripherals (Keyboard, LCD, CODECS, Serial Ports) such as +// const TUint KwVariantKeyColLshift = 7; +// #define KwVariantLcdBpp TNaviEngine::ELcd8BitsPerPixel +// const TUint KwVariantLcdMaxColors = 4096; +// const TUint KwVariantCodecMaxVolume = 0; +// +// - Off-chip hardware control blocks (addresses, register make-up) +// +// - Interrupts (second-level Interrupt controller base address, register make-up): +// (EXAMPLE ONLY:) +const TUint32 KHwVariantPhysBase = 0x40000000; +const TUint32 KHoVariantRegSpacing = 0x200; + +const TUint32 KHoBaseIntCont = 0x0B*KHoVariantRegSpacing; + +const TUint32 KHoIntContEnable = 0x00; // offsets from KHwVariantPhysBase+KHoBaseIntCont +const TUint32 KHoIntContPending = 0x04; +// other Variant and external blocks Base adrress offsets to KHwVariantPhysBase + + +// TO DO: (optional) +// +// Enumerate here all Variant (2nd level) interrupt sources. It could be a good idea to enumerate them in a way that +// facilitates operating on the corresponding interrupt controller registers (e.g using their value as a shift count) +// +// (EXAMPLE ONLY:) +enum TTemplateInterruptId + { + // the top-level bit is set to distinguish from first level (ASSP) Interrupts + EXIntIdA=0x80000000, + EXIntIdB=0x80000001, + // ... + EXIntIdZ=0x80000019, + + ENumXInts=0x1A + }; + +// +// TO DO: (optional) +// +// Define here some commonly used Variant (2nd level) interrupts +// +// (EXAMPLE ONLY:) +const TInt KIntIdKeyboard=EXIntIdB; + +class Variant + { + // below is a selection of functions usually implemented at this level. This do not constitute a mandatory + // set and it might not be relevant for your hardware... +public: + /** + * initialisation + */ + static void Init3(); + /** + * Returns the Linear Base address of the Variant Hardware + */ + IMPORT_C static TUint BaseLinAddress(); + /** + * When invoked, turns off all power supplies + */ + IMPORT_C static void PowerReset(); + /** + * When invoked, it marks the Serial port used for outputting debug strings as requiring re-initialisation + * As in, for example, the serial port was used by a device driver or the system is coming back from Standby + */ + IMPORT_C static void MarkDebugPortOff(); + /** + * When invoked, read the state of on-board switches + * @return A bitmask with the state of on-board switches + */ + IMPORT_C static TUint Switches(); + // other functions to access hardware not covered by specific device-drivres, which may be called from drivers + // or platform-specifc code + // ... +public: + static TUint32 iBaseAddress; + // (optional): May need to have a follower variable to store the value of a read only register initialised at boot time + // static TUint aFollower; + }; + +#endif + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/inc/lffsdev.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/inc/lffsdev.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,289 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\inc\lffsdev.h +* Header file for a Logging Flash file system (LFFS) physical device driver +* for a standard Common Flash Interface (CFI) based NOR flash chip. +* This file is part of the NE1_TBVariant Base port +* +*/ + + + +#ifndef __LFFSDEV_H__ +#define __LFFSDEV_H__ + +#include +#include + +#define FLASH_FAULT() Kern::Fault("LFFSDEV",__LINE__) + +// +// TO DO: (mandatory) +// +// Define the bus width (typically this will be 16 or 32) +// and the number of devices spanning the bus (typically 1, 2 or 4). +// +// Possible value are : FLASH_BUS_WIDTH FLASH_BUS_DEVICES +// 32 1 1 x 32 bit device +// 32 2 2 x 16 bit devices +// 32 4 4 x 8 bit devices +// 16 1 1 x 16 bit device +// 16 2 2 x 8 bit devices +// +// +#define FLASH_BUS_WIDTH 32 // EXAMPLE_ONLY +#define FLASH_BUS_DEVICES 2 // EXAMPLE_ONLY + + + +#if FLASH_BUS_WIDTH == 32 + #define TFLASHWORD TUint32 + #define FLASH_BYTES_TO_WORDS(aNumBytes) (aNumBytes >> 2) + #define FLASH_ADDRESS_IN_BYTES(aWordAddr) (aWordAddr << 2) + #define FLASH_ERASE_WORD_VALUE 0xFFFFFFFF +#elif FLASH_BUS_WIDTH == 16 + #define TFLASHWORD TUint16 + #define FLASH_BYTES_TO_WORDS(aNumBytes) (aNumBytes >> 1) + #define FLASH_ADDRESS_IN_BYTES(aWordAddr) (aWordAddr << 1) + #define FLASH_ERASE_WORD_VALUE 0xFFFF +#else // FLASH_BUS_WIDTH == 8 + #define TFLASHWORD TUint8 + #define FLASH_BYTES_TO_WORDS(aNumBytes) aNumBytes + #define FLASH_ADDRESS_IN_BYTES(aWordAddr) aWordAddr + #define FLASH_ERASE_WORD_VALUE 0xFF +#endif + +#define BUS_WIDTH_PER_DEVICE (FLASH_BUS_WIDTH / FLASH_BUS_DEVICES) + +/******************************************** +Common Flash Interface (CFI) definitions for various +combinations of FLASH_BUS_WIDTH and FLASH_BUS_DEVICES + ********************************************/ +// +// TO DO: (optional) +// Delete the definitions that are not applicable to your device +// +#if FLASH_BUS_WIDTH == 32 && FLASH_BUS_DEVICES == 1 // 1x32bit devices on 32bit bus + +const TFLASHWORD KCmdReadArray = 0x000000FF; // Set read array command +const TFLASHWORD KCmdReadStatusRegister = 0x00000070; // Read status register command +const TFLASHWORD KCmdClearStatusRegister = 0x00000050; // Clear status register error bits command +const TFLASHWORD KCmdWriteToBuffer = 0x000000E8; // Write to buffer setup command +const TFLASHWORD KCmdBlockErase = 0x00000020; // Block erase command +const TFLASHWORD KCmdEraseSuspend = 0x000000B0; // Erase suspend command +const TFLASHWORD KCmdEraseResume = 0x000000D0; // Erase resume command (actually a confirm) +const TFLASHWORD KCmdConfirm = 0x000000D0; // Confirm command +const TFLASHWORD KCmdReadIdentifiers = 0x00000090; // Read Flash identifiers command +const TFLASHWORD KCmdReadQuery = 0x00000098; // Read Flash Query info command + +const TFLASHWORD KStsReady = 0x00000080; // Ready bit +const TFLASHWORD KStsSuspended = 0x00000040; // Suspend bit +const TFLASHWORD KStsEraseError = 0x00000020; // Erase error bit +const TFLASHWORD KStsWriteError = 0x00000010; // Write error bit +const TFLASHWORD KStsVppLow = 0x00000008; // Vpp low bit +const TFLASHWORD KStsReserved = 0x00000004; // Reserved bit (not used) +const TFLASHWORD KStsLocked = 0x00000002; // Locked bit +const TFLASHWORD KStsReserved2 = 0x00000001; // Reserved bit + +#elif FLASH_BUS_WIDTH == 32 && FLASH_BUS_DEVICES == 2 // 2x16bit devices on 32bit bus + +const TFLASHWORD KCmdReadArray = 0x00FF00FF; // Set read array command +const TFLASHWORD KCmdReadStatusRegister = 0x00700070; // Read status register command +const TFLASHWORD KCmdClearStatusRegister = 0x00500050; // Clear status register error bits command +const TFLASHWORD KCmdWriteToBuffer = 0x00E800E8; // Write to buffer setup command +const TFLASHWORD KCmdBlockErase = 0x00200020; // Block erase command +const TFLASHWORD KCmdEraseSuspend = 0x00B000B0; // Erase suspend command +const TFLASHWORD KCmdEraseResume = 0x00D000D0; // Erase resume command (actually a confirm) +const TFLASHWORD KCmdConfirm = 0x00D000D0; // Confirm command +const TFLASHWORD KCmdReadIdentifiers = 0x00900090; // Read Flash identifiers command +const TFLASHWORD KCmdReadQuery = 0x00980098; // Read Flash Query info command + +const TFLASHWORD KStsReady = 0x00800080; // Ready bit +const TFLASHWORD KStsSuspended = 0x00400040; // Suspend bit +const TFLASHWORD KStsEraseError = 0x00200020; // Erase error bit +const TFLASHWORD KStsWriteError = 0x00100010; // Write error bit +const TFLASHWORD KStsVppLow = 0x00080008; // Vpp low bit +const TFLASHWORD KStsReserved = 0x00040004; // Reserved bit (not used) +const TFLASHWORD KStsLocked = 0x00020002; // Locked bit +const TFLASHWORD KStsReserved2 = 0x00010001; // Reserved bit + +#elif FLASH_BUS_WIDTH == 32 && FLASH_BUS_DEVICES == 4 // 4x8bit devices on 32bit bus + +const TFLASHWORD KCmdReadArray = 0xFFFFFFFF; // Set read array command +const TFLASHWORD KCmdReadStatusRegister = 0x70707070; // Read status register command +const TFLASHWORD KCmdClearStatusRegister = 0x50505050; // Clear status register error bits command +const TFLASHWORD KCmdWriteToBuffer = 0xE8E8E8E8; // Write to buffer setup command +const TFLASHWORD KCmdBlockErase = 0x20202020; // Block erase command +const TFLASHWORD KCmdEraseSuspend = 0xB0B0B0B0; // Erase suspend command +const TFLASHWORD KCmdEraseResume = 0xD0D0D0D0; // Erase resume command (actually a confirm) +const TFLASHWORD KCmdConfirm = 0xD0D0D0D0; // Confirm command +const TFLASHWORD KCmdReadIdentifiers = 0x90909090; // Read Flash identifiers command +const TFLASHWORD KCmdReadQuery = 0x98989898; // Read Flash Query info command + +const TFLASHWORD KStsReady = 0x80808080; // Ready bit +const TFLASHWORD KStsSuspended = 0x40404040; // Suspend bit +const TFLASHWORD KStsEraseError = 0x20202020; // Erase error bit +const TFLASHWORD KStsWriteError = 0x10101010; // Write error bit +const TFLASHWORD KStsVppLow = 0x08080808; // Vpp low bit +const TFLASHWORD KStsReserved = 0x04040404; // Reserved bit (not used) +const TFLASHWORD KStsLocked = 0x02020202; // Locked bit +const TFLASHWORD KStsReserved2 = 0x01010101; // Reserved bit + +#elif FLASH_BUS_WIDTH == 16 && FLASH_BUS_DEVICES == 1 // 1x16bit devices on 16bit bus + +const TFLASHWORD KCmdReadArray = 0x00FF; // Set read array command +const TFLASHWORD KCmdReadStatusRegister = 0x0070; // Read status register command +const TFLASHWORD KCmdClearStatusRegister = 0x0050; // Clear status register error bits command +const TFLASHWORD KCmdWriteToBuffer = 0x00E8; // Write to buffer setup command +const TFLASHWORD KCmdBlockErase = 0x0020; // Block erase command +const TFLASHWORD KCmdEraseSuspend = 0x00B0; // Erase suspend command +const TFLASHWORD KCmdEraseResume = 0x00D0; // Erase resume command (actually a confirm) +const TFLASHWORD KCmdConfirm = 0x00D0; // Confirm command +const TFLASHWORD KCmdReadIdentifiers = 0x0090; // Read Flash identifiers command +const TFLASHWORD KCmdReadQuery = 0x0098; // Read Flash Query info command + +const TFLASHWORD KStsReady = 0x0080; // Ready bit +const TFLASHWORD KStsSuspended = 0x0040; // Suspend bit +const TFLASHWORD KStsEraseError = 0x0020; // Erase error bit +const TFLASHWORD KStsWriteError = 0x0010; // Write error bit +const TFLASHWORD KStsVppLow = 0x0008; // Vpp low bit +const TFLASHWORD KStsReserved = 0x0004; // Reserved bit (not used) +const TFLASHWORD KStsLocked = 0x0002; // Locked bit +const TFLASHWORD KStsReserved2 = 0x0001; // Reserved bit + +#elif FLASH_BUS_WIDTH == 16 && FLASH_BUS_DEVICES == 2 // 2x8bit devices on 16bit bus +const TFLASHWORD KCmdReadArray = 0xFFFF; // Set read array command +const TFLASHWORD KCmdReadStatusRegister = 0x7070; // Read status register command +const TFLASHWORD KCmdClearStatusRegister = 0x5050; // Clear status register error bits command +const TFLASHWORD KCmdWriteToBuffer = 0xE8E8; // Write to buffer setup command +const TFLASHWORD KCmdBlockErase = 0x2020; // Block erase command +const TFLASHWORD KCmdEraseSuspend = 0xB0B0; // Erase suspend command +const TFLASHWORD KCmdEraseResume = 0xD0D0; // Erase resume command (actually a confirm) +const TFLASHWORD KCmdConfirm = 0xD0D0; // Confirm command +const TFLASHWORD KCmdReadIdentifiers = 0x9090; // Read Flash identifiers command +const TFLASHWORD KCmdReadQuery = 0x9898; // Read Flash Query info command + +const TFLASHWORD KStsReady = 0x8080; // Ready bit +const TFLASHWORD KStsSuspended = 0x4040; // Suspend bit +const TFLASHWORD KStsEraseError = 0x2020; // Erase error bit +const TFLASHWORD KStsWriteError = 0x1010; // Write error bit +const TFLASHWORD KStsVppLow = 0x0808; // Vpp low bit +const TFLASHWORD KStsReserved = 0x0404; // Reserved bit (not used) +const TFLASHWORD KStsLocked = 0x0202; // Locked bit +const TFLASHWORD KStsReserved2 = 0x0101; // Reserved bit + +#endif + +// address at which to issue the Query command +const TUint32 KCmdReadQueryOffset = 0x55; + +const TUint32 KQueryOffsetQRY = 0x10; +const TUint32 KQueryOffsetSizePower = 0x27; +const TUint32 KQueryOffsetWriteBufferSizePower = 0x2A; +const TUint32 KQueryOffsetErasePartitions = 0x2C; +const TUint32 KQueryOffsetEraseBlockCount = 0x2D; +const TUint32 KQueryOffsetEraseBlockSize = 0x2F; + +/******************************************** + * Driver definitions + ********************************************/ +const TInt KMaxWriteSetupAttempts = 8; +const TInt KMaxEraseResumeAttempts = 32; + +const TInt KDataBufSize=1024; + + +// TO DO: (mandatory) +// Define the following timeouts in terms of timer ticks +// This is only example code... you may need to modify it for your hardware +// The examples given here assume a timer clock frequency of 3.6864MHz +const TUint32 KFlashWriteTimerPeriod = 1500; // 1500 ticks @ 3.6864MHz = 406us +const TUint32 KFlashWriteTimerRetries = 3; // total 1.2ms +const TUint32 KFlashSuspendTimerPeriod = 1500; // 1500 ticks @ 3.6864MHz = 406us +const TUint32 KFlashSuspendTimerRetries = 3; // total 1.2ms +const TUint32 KFlashEraseTimerPeriod = 100000; // 100000 ticks @ 3.6864MHz = 27ms +const TUint32 KFlashEraseTimerRetries = 100; // total 2.7sec +const TInt KEraseSuspendHoldOffTime = 130; // 130ms + +/******************************************** + * Media driver class + ********************************************/ +// +// TO DO: (optional) +// +// Add any private functions and data you require +// +class DMediaDriverFlashNE1_TB : public DMediaDriverFlash + { +public: + enum TWriteState {EWriteIdle=0,EWriting=1}; + enum TEraseState {EEraseIdle=0,EErase=1,EEraseNoSuspend=2,ESuspendPending=3,ESuspending=4,ESuspended=5}; + enum TEvent {EPollTimer=1,ETimeout=2,EHoldOffEnd=4}; + + DMediaDriverFlashNE1_TB(TInt aMediaId); + + // replacing pure virtual - FLASH device specific stuff + virtual TInt Initialise(); + virtual TUint32 EraseBlockSize(); + virtual TUint32 TotalSize(); + virtual TInt DoRead(); + virtual TInt DoWrite(); + virtual TInt DoErase(); + +private: + void IPostEvents(TUint32 aEvents); + void HandleEvents(TUint32 aEvents); + void ClearEvents(TUint32 aEvents); + void StartPollTimer(TUint32 aPeriod, TUint32 aRetries); + void StartPollTimer(); + void StartHoldOffTimer(); + void CancelHoldOffTimer(); + void StartErase(); + void SuspendErase(); + void WriteStep(); + void DoFlashReady(TUint32 aStatus); + void DoFlashTimeout(); + void StartPendingRW(); + TUint32 ReadQueryData8(TUint32 aOffset); + TUint32 ReadQueryData16(TUint32 aOffset); + void ReadFlashParameters(); + static void Isr(TAny* aPtr); + static void HoldOffTimerFn(TAny* aPtr); + static void EventDfc(TAny* aPtr); + +private: + TWriteState iWriteState; + TEraseState iEraseState; + TLinAddr iBase; + TUint32 iEraseBlockSize; + TUint32 iTotalSize; + TUint32 iWriteBufferSize; + TUint32 iWritePos; + TInt iDataBufPos; + TInt iDataBufRemain; + TUint8* iData; // data being written + TUint32 iErasePos; + NTimer iHoldOffTimer; + TUint32 iEvents; + TDfc iEventDfc; + TUint32 iPollPeriod; + TUint32 iPollRetries; + TUint32 iEraseError; + TInt iWriteError; + TInt iEraseAttempt; + DPlatChunkHw* iFlashChunk; + }; + +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/inc/mconf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/inc/mconf.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\inc\mconf.h +* NE1_TBVariant Persistent Machine Configuration +* +*/ + + + +#ifndef __MCONF_H__ +#define __MCONF_H__ +#include + +class TDigitizerCalibrateValues + { +public: + TInt iR11; + TInt iR12; + TInt iR21; + TInt iR22; + TInt iTx; + TInt iTy; + }; + +class TTemplateMachineConfig : public TMachineConfig + { +public: + TSoundInfoV1 iSoundInfo; + TOnOffInfoV1 iOnOffInfo; + TTimeK iMainBatteryInsertionTime; + Int64 iMainBatteryInUseMicroSeconds; + Int64 iExternalPowerInUseMicroSeconds; + Int64 iMainBatteryMilliAmpTicks; + TDigitizerCalibrateValues iCalibration; + TDigitizerCalibrateValues iCalibrationSaved; + TDigitizerCalibrateValues iCalibrationFactory; + }; + +typedef TTemplateMachineConfig TActualMachineConfig; + +inline TActualMachineConfig& TheActualMachineConfig() + {return (TActualMachineConfig&)Kern::MachineConfig();} + +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/inc/nand_fbr_offset.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/inc/nand_fbr_offset.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* bsp\hwip_nec_naviengine\ne1_tb\inc\NAND_FBR_OFFSET.H +* +*/ + + + +#ifndef __NAND_FBR_OFFSET_H__ +#define __NAND_FBR_OFFSET_H__ + +/** +Defines the offset at which the FBR appears in the first block +@internalTechnology +*/ +const TInt KNandFbrSectorOffset=0; +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/inc/ne1_tb_power.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/inc/ne1_tb_power.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,205 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\inc\ne1_tb_power.h +* NE1_TBVariant Power Management Header +* (see also assp.cpp for a discussion on Sleep modes and xyin.cpp for example +* of usage of Resource Manager and Peripheral self power down and interaction +* with Power Controller for Wakeup Events) +* +*/ + + + +#ifndef __PM_STD_H__ +#define __PM_STD_H__ +#include +#include "variant.h" +#include +#ifdef __SMP__ +#include +#endif +#include +#if defined (__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__) +#include +#include "smpidlehandler.h" +#endif + +#define __PM_ASSERT_ALWAYS(aCond) \ + __ASSERT_ALWAYS( (aCond), \ + ( \ + Kern::Printf("Assertion '" #aCond "' failed;\nFile: '" __FILE__ "' Line: %d\n", __LINE__), \ + Kern::Fault("Power Management", 1) \ + ) ) + +#define __PM_ASSERT_DEBUG(aCond) \ + __ASSERT_DEBUG( (aCond), \ + ( \ + Kern::Printf("Assertion '" #aCond "' failed;\nFile: '" __FILE__ "' Line: %d\n", __LINE__), \ + Kern::Fault("Power Management", 1) \ + ) ) + +class TNE1_TBPowerController; +class DNE1_TBPowerController; + +struct TRetireEngageCb + { + TRetireEngageCb(TDfcFn aFunction, TAny* aPtr, TInt aPriority) + :iDfc(aFunction,aPtr,aPriority) + {}; + TRetireEngageCb(TDfcFn aFunction, TAny* aPtr, TDfcQue* aDfcQ, TInt aPriority) + :iDfc(aFunction,aPtr,aDfcQ,aPriority) + {}; + TDfc iDfc; + TInt iResult; + TAny* iParam; + }; + + + +struct SRetireCall + { + SRetireCall(TInt aCpu,TRetireEngageCb& aCb); +#if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__) && defined(SIMULATE_RETIREMENT) + static void RetireCoreDfcFn(TAny*); + void Call() { iTimer.OneShot(0);} // use a timer instead of Dfc as call can race with timer ISR + NTimer iTimer; // by using a timer we are kinda sure we will run between ticks + TInt iCpu; + TRetireEngageCb& iCb; + const TUint32 iAllCpusMask; +#endif + }; + + +struct SEngageCall + { + SEngageCall(TInt aCpu,TRetireEngageCb& aCb); +#if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__) && defined(SIMULATE_RETIREMENT) + static void EngageCoreDfcFn(TAny*); + void Call() { iDfc.Enque();} + TDfc iDfc; + TInt iCpu; + TRetireEngageCb& iCb; +#endif + }; + +#if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__) + +class DNE1_TBPowerController; + +NONSHARABLE_CLASS(DNE1_SMPIdleHandler) : public DSMPIdleHandler + { +friend class SRetireCall; +friend class SEngageCall; + +public: + DNE1_SMPIdleHandler(DNE1_TBPowerController* aController); + TInt Initialise(); + TBool DoEnterIdle(TInt aCpuMask, TInt aStage, volatile TAny* aU); + TBool GetLowPowerMode(TInt aIdleTime, TInt &aLowPowerMode); + TBool EnterLowPowerMode(TInt aMode, TInt aCpuMask, TBool aLastCpu); +private: + void DoRetireCore(TInt aCpu, TLinAddr aReturnPoint); +#ifdef SIMULATE_RETIREMENT + static void IdleSteal(TAny*); +#endif + +private: +#ifdef SIMULATE_RETIREMENT + static volatile TUint32 iRetiredCores; + // static volatile TUint32 iEngagingCores; + TDfcQue** iIdleStealers; + TDfc** iIdleStealDfcs; + TDfcQue* iRetireEngageQue; +#endif + DNE1_TBPowerController* iController; + }; + +#endif + +// +// TO DO: (mandatory) +// +// Definition of the DPowerController derived class +// +NONSHARABLE_CLASS(DNE1_TBPowerController) : public DPowerController + { +friend class TNE1_TBPowerController; + +public: // from DPowerController + void CpuIdle(); + void EnableWakeupEvents(); + void AbsoluteTimerExpired(); + void DisableWakeupEvents(); + void PowerDown(TTimeK aWakeupTime); + void IdleTickSuppresionEntry(TUint32 aWakeDelay, TInt aNextTimer); + void IdleTickSuppresionRestore(); +public: + DNE1_TBPowerController(); +private: + static TInt ClearTimerInterrupt(); // return pending interrupt or 1023 if non pending + void DoStandby(TBool aTimed, TUint32 aWakeupRTC); +public: + static const TUint32 KCyclesPerTick; // clock cycles per ms tick + static const TInt KMaxSleepTicks; // max number of ticks that can be slept + static const TUint32 KWakeUpBeforeTick; // The time (in cycles) that we required to before next tick is due to expire (i.e. after idle tick suppression) + static const TUint32 KTooCloseToTick; // In cycles abort idle tick suppresion if we very close current tick edge + static const TUint32 KMinTimeToTick; // In cyles, if time to next interrupt is less than this value in wakeup + // ... we need to update tick in idle tick restore + static const TInt KMinIdleTicks; // Minimum amount of ticks we wish to enter power saving mode + +private: +#if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__) + DNE1_SMPIdleHandler iIdleHandler; +#endif +// const TUint32 iNumCpus; +// Idle tick supression related variables + TBool iWakeupEventsOn; + TUint32 iNextInterrupt; + TUint32 iOriginalTimerExpire; + TUint iIdleCount; // in SMP increased every time we do ITS + // in unicore, updated on every entry to CpuIdle + }; + + +// +// If you need to access to the Power Controller from Drivers/Extensions/Variant +// or access to Resource Manager then define an accessor class as below +// +class TNE1_TBPowerController + { +friend class SRetireCall; +friend class SEngageCall; +public: + // to allow Variant/Drivers/Extensions access to Resource Manager + // used by drivers/extensions to signal a wakeup event to Power Controller + IMPORT_C static void WakeupEvent(); + IMPORT_C static void RetireCore(TInt aCpu, TRetireEngageCb& aCb); + IMPORT_C static void EngageCore(TInt aCpu, TRetireEngageCb& aCb); + IMPORT_C static TUint IdleCount(); + + inline static void RegisterPowerController(DNE1_TBPowerController* aPowerController); +private: + static DNE1_TBPowerController* iPowerController; +#if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__) + static DNE1_SMPIdleHandler* iIdleHandler; +#endif + }; + + + +#include "ne1_tb_power.inl" + +#endif + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/inc/ne1_tb_power.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/inc/ne1_tb_power.inl Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\inc\ne1_tb_power.inl +* NE1_TBVariant Power Management Inline file +* -/-/-/-/-/-/-/-/-/ class TNE1_TBPowerController /-/-/-/-/-/-/-/-/-/ +* +*/ + + + +inline void TNE1_TBPowerController::RegisterPowerController(DNE1_TBPowerController* aPowerController) + { + __PM_ASSERT(!iPowerController); + iPowerController = aPowerController; +#if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__) + iIdleHandler = &aPowerController->iIdleHandler; +#endif + } + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/inc/powerresources.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/inc/powerresources.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,208 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\specific\powerresources.h +* +*/ + + + +#ifndef __POWERRESOURCES_H__ +#define __POWERRESOURCES_H__ + +/** Enumeration for static resource Id */ +enum ResourceId + { + /** Resource Id for I2S 0 MCLK Resource */ + ENE1_TBI2S0MclkResource = 1, + /** Resource Id for I2S 1 MCLK Resource */ + ENE1_TBI2S1MclkResource = 2, + /** Resource Id for I2S 2 MCLK Resource */ + ENE1_TBI2S2MclkResource = 3, + /** Resource Id for I2S 3 MCLK Resource */ + ENE1_TBI2S3MclkResource = 4, + /** Resource Id for I2S 0 SCLK Resource */ + ENE1_TBI2S0SclkResource = 5, + /** Resource Id for I2S 1 SCLK Resource */ + ENE1_TBI2S1SclkResource = 6, + /** Resource Id for I2S 2 SCLK Resource */ + ENE1_TBI2S2SclkResource = 7, + /** Resource Id for I2S 3 SCLK Resource */ + ENE1_TBI2S3SclkResource = 8, + /** Resource Id for CSI 0 clock Resource */ + ENE1_TBCSI0ClockResource = 9, + /** Resource Id for CSI 1 clock Resource */ + ENE1_TBCSI1ClockResource = 10, + /** Resource Id for Display DCLK Resource */ + ENE1_TBDisplayDclkResource = 11, + /** Resource Id for LCD Resource */ + ENE1_TBLcdResource = 12, + /** Resource Id for Board Power Resource */ + ENE1_TBBoardPowerResource = 13, + /** Resource Id for PCI Clock enable resource */ + ENE1_TBPCIClkResource = 14, + /** Add any new resource above this */ + EMaxResourceCount + }; + + +/** Resource name for board power.*/ +_LIT(KBoardPower, "NE1_TBBoardPower"); + +/** Resource name for LCD Power. */ +_LIT(KLcdPower, "NE1_TBLcdPower"); + +/** Resource name for PCI clock enable resource */ +_LIT(KPCIClk, "NE1_TBPCIClk"); + +/** Enumeration for binary resource + Possible values for board power and lcd power resource. +*/ +enum EBinaryResPower + { + /** Power OFF */ + E_OFF, + /** Power ON */ + E_ON + }; + +/** Resource name for display Dclk */ +_LIT(KDisplayDclk, "NE1_TBDisplayDclk"); + +/** Enumeration of possible programmable divider for display DCLK */ +enum TDisplayDclk + { + /** 399MHz divide by 20 */ + EDisplayDclk19950KHz = 0, + /** 399MHz divide by 19 */ + EDisplayDclk21000KHz, + /** 399MHz divide by 18 */ + EDisplayDclk22166KHz, + /** 399MHz divide by 17 */ + EDisplayDclk23470KHz, + /** 399MHz divide by 16 */ + EDisplayDclk24937KHz, + /** 399MHz divide by 15 */ + EDisplayDclk26600KHz, + /** 399MHz divide by 14 */ + EDisplayDclk28500KHz, + /** 399MHz divide by 13 */ + EDisplayDclk30692KHz, + /** 399MHz divide by 12 */ + EDisplayDclk33250KHz, + /** 399MHz divide by 11 */ + EDisplayDclk36272KHz, + /** 399MHz divide by 10 */ + EDisplayDclk39900KHz, + /** 399MHz divide by 9 */ + EDisplayDclk44333KHz, + /** 399MHz divide by 8 */ + EDisplayDclk49875KHz, + /** 399MHz divide by 7 */ + EDisplayDclk57000KHz, + /** 399MHz divide by 6 */ + EDisplayDclk66500KHz, + /** 399MHz divide by 5 */ + EDisplayDclk79800KHz + }; + +/** Resource name for CSI 0 clock */ +_LIT(KCSI0Clock, "NE1_TBCSI0Clock"); + +/** Resource name for CSI 1 clock */ +_LIT(KCSI1Clock, "NE1_TBCSI1Clock"); + +/** Enumeration of possible frequency for CSI clock */ +enum TCSIClock + { + /** SCLK1 (slave mode) */ + ECSIClkSck1 = 0, + /** 1/512 PCLK frequency for CSI clock (master mode) */ + ECSIClk130KHz, + /** 1/256 PCLK frequency for CSI clock (master mode) */ + ECSIClk260KHz, + /** 1/128 PCLK frequency for CSI clock (master mode) */ + ECSIClk521KHz, + /** 1/64 PCLK frequency for CSI clock (master mode) */ + ECSIClk1040KHz, + /** 1/32 PCLK frequency for CSI clock (master mode) */ + ECSIClk2080KHz, + /** 1/16 PCLK frequency for CSI clock (master mode) */ + ECSIClk4170KHz, + /** 1/4 PCLK frequency for CSI clock (master mode) */ + ECSIClk16670KHz + }; + +/** Resource name for I2S0 MCLK */ +_LIT(KI2S0Mclk, "NE1_TBI2S0Mclk"); +/** Resource name for I2S1 MCLK */ +_LIT(KI2S1Mclk, "NE1_TBI2S1Mclk"); +/** Resource name for I2S2 MCLK */ +_LIT(KI2S2Mclk, "NE1_TBI2S2Mclk"); +/** Resource name for I2S3 MCLK */ +_LIT(KI2S3Mclk, "NE1_TBI2S3Mclk"); + +/** Enumeration of possible frequency for I2S MCLK */ +enum TI2SMclk + { + /** Enable MCLK masking */ + EI2SMclkMask = -1, + /** 36.864MHz MCLK frequency */ + EI2SMclk36864KHz = 0, + /** 24.576MHz MCLK frequency */ + EI2SMclk24576KHz = 1, + /** 18.432MHz MCLK frequency */ + EI2SMclk18432KHz = 2, + /** 33.8688MHz MCLK frequency */ + EI2SMclk33868KHz = 4, + /** 22.5792MHz MCLK frequency */ + EI2SMclk22579KHz = 5, + /** 16.9344MHz MCLK frequency */ + EI2SMclk16934KHz = 6 + }; + +/** Resource name for I2S0 SCLK */ +_LIT(KI2S0Sclk, "NE1_TBI2S0Sclk"); +/** Resource name for I2S1 SCLK */ +_LIT(KI2S1Sclk, "NE1_TBI2S1Sclk"); +/** Resource name for I2S2 SCLK */ +_LIT(KI2S2Sclk, "NE1_TBI2S2Sclk"); +/** Resource name for I2S3 SCLK */ +_LIT(KI2S3Sclk, "NE1_TBI2S3Sclk"); + +/** Enumeration of possible frequency for I2S SCLK */ +enum TI2SSclk + { + /** 8KHz Sampling frequency in master mode */ + EI2SSclk8000Hz = 0, + /** 12KHz Sampling frequency in master mode */ + EI2SSclk12000Hz = 1, + /** 16KHz Sampling frequency in master mode */ + EI2SSclk16000Hz = 2, + /** 24KHz Sampling frequency in master mode */ + EI2SSclk24000Hz = 3, + /** 32KHz Sampling frequency in master mode */ + EI2SSclk32000Hz = 4, + /** 48KHz Sampling frequency in master mode */ + EI2SSclk48000Hz = 5, + /** 11.025KHz Sampling frequency in master mode */ + EI2SSclk11025Hz = 8, + /** 22.05KHz Sampling frequency in master mode */ + EI2SSclk22050Hz = 9, + /** 44.1KHz Sampling frequency in master mode */ + EI2SSclk44100Hz = 10 + }; + +#endif //__POWERRESOURCES_H__ + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/inc/rebootdrv_plat.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/inc/rebootdrv_plat.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* bsp\hwip_nec_naviengine\ne1_tb\inc\rebootdrv_plat.h +* +*/ + + + +#ifndef __REBOOTDRV_NAVI_H__ +#define __REBOOTDRV_NAVI_H__ + +// This dummy definition is needed because rebootdrv_plat.h includes +// this file and depends on it +const TLinAddr KPageDirectoryBase=0; + +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/inc/resmanpsl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/inc/resmanpsl.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,224 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\inc\resmanpsl.h +* +*/ + + + +#ifndef __RESOURCECONTROLPSL_H__ +#define __RESOURCECONTROLPSL_H__ + +#include +#include "powerresources.h" +#include + +#define SHIFT_BY_8 8 +#define SHIFT_BY_9 9 +#define SHIFT_BY_16 16 +#define SHIFT_BY_24 24 + +#define CSI_UNIT_ENABLE 0x80 +#define CSI_RESET 0x10000000 + +const TUint KClearBit0 = 0x1; +const TUint KClearBit0_2 = 0x7; +const TUint KClearBit0_3 = 0xF; +const TUint KClearBit09 = 0x200; +const TUint KSetBit09 = 0x200; +const TUint KClearBit18 = 0x40000; +const TUint KSetBit18 = 0x40000; +const TUint KClearBit8_11 = 0xF00; +const TUint KClearBit19 = 0x80000; +const TUint KSetBit19 = 0x80000; +const TUint KClearBit16_19 = 0xF0000; +const TUint KClearBit20 = 0x100000; +const TUint KSetBit20 = 0x100000; +const TUint KClearBit24_27 = 0xF000000; +const TUint KClearBit21 = 0x200000; +const TUint KSetBit21 = 0x200000; + +//Initial resource controller pool definition +#define KERNEL_CLIENTS 14 +#define USER_CLIENTS 1 +#define CLIENT_LEVELS 14 +#define REQUESTS 0 + +const TUint KDfcQThreadPriority = 28; +_LIT(KResmanName, "NE1_TBResMan"); + +/** Macro definition to register resource */ +#define REGISTER_RESOURCE(resource, resourceArray, resourceCount) \ + { \ + pR = new resource(); \ + if(!pR) \ + { \ + for(TUint count = 0; count < resourceCount; count++) \ + { \ + delete resourceArray[count]; \ + } \ + delete[] resourceArray; \ + return KErrNoMemory; \ + } \ + resourceArray[resourceCount++] = pR; \ + } + +//Power Resource Controller derived class for naviengine. +class DNE1_TBPowerResourceController : public DPowerResourceController + { +public: + DNE1_TBPowerResourceController(); + TInt DoInitController(); + TInt DoRegisterStaticResources(DStaticPowerResource**& aStaticResourceArray, TUint16& aStaticResourceCount); + }; + + +// Resource definition for I2S0 MCLK frequency divider setting +class DNE1_TBI2S0MclkResource : public DStaticPowerResource + { +public: + DNE1_TBI2S0MclkResource(); + TInt GetInfo(TDes8* aInfo)const; + TInt DoRequest(TPowerRequest& aRequest); + }; + +//Resource definition for I2S1 MCLK frequency divider setting +class DNE1_TBI2S1MclkResource : public DStaticPowerResource + { +public: + DNE1_TBI2S1MclkResource(); + TInt GetInfo(TDes8* aInfo)const; + TInt DoRequest(TPowerRequest& aRequest); + }; + +//Resource definition for I2S2 MCLK frequency divider setting +class DNE1_TBI2S2MclkResource : public DStaticPowerResource + { +public: + DNE1_TBI2S2MclkResource(); + TInt GetInfo(TDes8* aInfo)const; + TInt DoRequest(TPowerRequest& aRequest); + }; + +//Resource definition for I2S3 MCLK frequency divider setting +class DNE1_TBI2S3MclkResource : public DStaticPowerResource + { +public: + DNE1_TBI2S3MclkResource(); + TInt GetInfo(TDes8* aInfo)const; + TInt DoRequest(TPowerRequest& aRequest); + }; + +//Resource definition for I2S0 Sampling frequency setting +class DNE1_TBI2S0SclkResource : public DStaticPowerResource + { +public: + DNE1_TBI2S0SclkResource(); + TInt GetInfo(TDes8* aInfo)const; + TInt DoRequest(TPowerRequest& aRequest); + }; + +//Resource definition for I2S1 sampling frequency setting +class DNE1_TBI2S1SclkResource : public DStaticPowerResource + { +public: + DNE1_TBI2S1SclkResource(); + TInt GetInfo(TDes8* aInfo)const; + TInt DoRequest(TPowerRequest& aRequest); + }; + +//Resource definition for I2S2 sampling frequency setting +class DNE1_TBI2S2SclkResource : public DStaticPowerResource + { +public: + DNE1_TBI2S2SclkResource(); + TInt GetInfo(TDes8* aInfo)const; + TInt DoRequest(TPowerRequest& aRequest); + }; + +//Resource definition for I2S3 sampling frequency setting +class DNE1_TBI2S3SclkResource : public DStaticPowerResource + { +public: + DNE1_TBI2S3SclkResource(); + TInt GetInfo(TDes8* aInfo)const; + TInt DoRequest(TPowerRequest& aRequest); + }; + +//Resource definition for Display clock (DCLK) setting +class DNE1_TBDisplayDclkResource : public DStaticPowerResource + { +public: + DNE1_TBDisplayDclkResource(); + TInt GetInfo(TDes8* aInfo)const; + TInt DoRequest(TPowerRequest& aRequest); + }; + +//Resource definition for LCD power +class DNE1_TBLcdResource : public DStaticPowerResource + { +public: + DNE1_TBLcdResource(); + TInt GetInfo(TDes8* aInfo)const; + TInt DoRequest(TPowerRequest& aRequest); + }; + +//Resource definition for board power +class DNE1_TBBoardPowerResource : public DStaticPowerResource + { +public: + DNE1_TBBoardPowerResource(); + TInt GetInfo(TDes8* aInfo)const; + TInt DoRequest(TPowerRequest& aRequest); + }; + +//Resource definition for CSI0 clock select +class DNE1_TBCSI0ClockResource : public DStaticPowerResource + { +public: + DNE1_TBCSI0ClockResource(); + TInt GetInfo(TDes8* aInfo)const; + TInt DoRequest(TPowerRequest& aRequest); + }; + +//Resource definition for CSI1 clock select +class DNE1_TBCSI1ClockResource : public DStaticPowerResource + { +public: + DNE1_TBCSI1ClockResource(); + TInt GetInfo(TDes8* aInfo)const; + TInt DoRequest(TPowerRequest& aRequest); + }; + +//Resource definition for PCL clock enable +class DNE1_TBPCIClockResource : public DStaticPowerResource + { +public: + DNE1_TBPCIClockResource(); + TInt GetInfo(TDes8* aInfo)const; + TInt DoRequest(TPowerRequest& aRequest); + }; + +//Resource definition for PCL clock enable +class DNE1_WakeupLatencyResource : public DStaticPowerResource + { +public: + DNE1_WakeupLatencyResource(); + TInt GetInfo(TDes8* aInfo)const; + TInt DoRequest(TPowerRequest& aRequest); + }; + +#endif //__RESOURCECONTROLPSL_H__ + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/inc/soundsc_plat.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/inc/soundsc_plat.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,167 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\inc\soundsc_plat.h +* Definitions for the NE1_TBVariant shared chunk sound physical device driver (PDD). +* +*/ + + + +/** + @file + @internalTechnology + @prototype +*/ + +#ifndef __SOUNDSC_PLAT_H__ +#define __SOUNDSC_PLAT_H__ + +#include +#include +#include +#include "cs42l51.h" + +// macro to print out thread context and CPU that thread is running on.. +#define __THREAD_AND_CPU Kern::Printf("(Thread %T, CPU: %d)\n", NKern::CurrentThread(), NKern::CurrentCpu()) +#define __KTRACE_SND(s) __KTRACE_OPT(KSOUND1, s) +//#define __KTRACE_SND(s) s + +// Fill in the maximum number of requests that may be outstanding on the playback and record DMA channels for this device. +const TInt KMaxDmaRequests=2; + +// Fill in the maximum transfer length supported on the playback and record DMA channels for this device. +const TInt KMaxDmaTransferLen=0x2000; + +// fifo threshold values for I2S transfers.. +const TInt KFifoThreshold = 8; + +// Forward declarations +class DNE1_TBSoundScDmaRequest; + +// Define the I2S channel number used by this driver +const TUint KI2sChanNum = 0; +/** +Factory class instantiated from ordinal 0. +The NE1_TBVariant physical device for the shared chunk sound driver used to create the DSoundScPdd-derived channel objects. +*/ +class DSoundScPddNE1_TB : public DPhysicalDevice + { +public: + DSoundScPddNE1_TB(); + ~DSoundScPddNE1_TB(); + virtual TInt Install(); + virtual void GetCaps(TDes8& aDes) const; + virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); + virtual TInt Validate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); +private: + // The DFC queue (used also by the LDD). + TDynamicDfcQue* iDfcQ; + + // A pointer to the audio codec object + RCS42AudioCodec* iCodec; + + friend class DNE1_TBSoundScPddChannel; + }; + +/** +The NE1_TBVariant physical device driver (PDD) for the playback shared chunk sound driver. +*/ +class DNE1_TBSoundScPddChannel : public DSoundScPdd + { +public: + explicit DNE1_TBSoundScPddChannel(TSoundDirection aSoundDirection); + ~DNE1_TBSoundScPddChannel(); + TInt DoCreate(); + + // Implementations of the pure virtual functions inherited from DSoundScPdd (called by LDD). + virtual TDfcQue* DfcQ(TInt aUnit); + virtual void GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo); + virtual void Caps(TDes8& aCapsBuf) const; + virtual TInt MaxTransferLen() const; + virtual TInt SetConfig(const TDesC8& aConfigBuf); + virtual TInt SetVolume(TInt aVolume); + virtual TInt StartTransfer(); + virtual TInt TransferData(TUint aTransferID,TLinAddr aLinAddr,TPhysAddr aPhysAddr,TInt aNumBytes); + virtual void StopTransfer(); + virtual TInt PauseTransfer(); + virtual TInt ResumeTransfer(); + virtual TInt PowerUp(); + virtual void PowerDown(); + virtual TInt CustomConfig(TInt aFunction,TAny* aParam); + void PlayCallback(TUint aTransferID,TInt aTransferResult,TInt aBytesTransferred); + +private: + void SetCaps(); + static void PowerUpCallback (TAny *aArg); + +private: + // A pointer to the PDD factory. + DSoundScPddNE1_TB* iPhysicalDevice; + // The capabilities of this device. + TSoundFormatsSupportedV02 iCaps; + // The playback DMA channel. + TDmaChannel* iDmaChannel; + // The DMA request structures used for transfers. + DNE1_TBSoundScDmaRequest* iDmaRequest[KMaxDmaRequests]; + // The number of outstanding DMA play requests on the DMA channel. + TInt iPendingPlay; + // A flag selecting the next DMA request for transfer. + TInt iFlag; + // current configuration + TCurrentSoundFormatV02 iCurrentConfig; + + // I2S direction (I2s::ETx or I2s::ERx) of this unit + I2s::TI2sDirection iI2sDirection; + + // Dfc, semaphore and status -used to power up the Codec in the context of the driver thread + TDfc iPowerUpDfc; + static NFastSemaphore iFastSem; + TInt iPowerUpStatus; + + friend class DSoundScPddNE1_TB; + friend class DNE1_TBSoundScDmaRequest; + }; + +/** +Wrapper function for a shared chunk sound driver DMA request. +*/ +class DNE1_TBSoundScDmaRequest : public DDmaRequest + { +public: + DNE1_TBSoundScDmaRequest(TDmaChannel& aChannel,DNE1_TBSoundScPddChannel* aPdd,TInt aMaxTransferSize=0); + ~DNE1_TBSoundScDmaRequest(); + TInt CreateMonoBuffer(); + TInt SetDmaTransfer(TUint aTransferID, TLinAddr aLinAddr, TInt aNumBytes); + static void DmaService(TResult aResult, TAny* aArg); +public: + // Pointer back to the PDD. + DNE1_TBSoundScPddChannel* iPdd; + // The transfer ID for this DMA request - supplied by the LDD. + TUint iTransferID; + // The transfer sizes in progress. + TUint iTransferSize; + +private: + // To facilitate mono support: + // Linear start address of the data supplied by the client.. + TLinAddr iAddrLinOrig; + + // buffers needed to store mono samples + TPhysAddr iBuffPhys; + TLinAddr iBufLin; + DPlatChunkHw* iChunk; + }; + +#endif /* __SOUNDSC_PLAT_H__ */ diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/inc/variant.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/inc/variant.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,136 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\inc\variant.h +* NE1_TBVariant Variant Header +* +*/ + + + +#ifndef __VA_STD_H__ +#define __VA_STD_H__ +#include "naviengine_priv.h" +#include "iolines.h" + +NONSHARABLE_CLASS(NE1_TBVariant) : public NaviEngineAssp + { +public: + NE1_TBVariant(); +public: + /** + * These are the mandatory Asic class functions which need to be implemented here. The other mandatory + * functions are implemented in NaviEngineAssp + */ + + /** + * initialisation + */ + virtual void Init1(); +#ifdef __SMP__ + virtual void Init2AP(); +#endif + virtual void Init3(); + + /** + * power management + * Device specific Idle: prepares the CPU to go into Idle and sets out the conditions to come out of it + */ + virtual void Idle(); + + /** + * HAL + * @param aFunction A TVariantHalFunction enumerated value + * @param a1 Optional input/output parameter + * @param a2 Optional input/output parameter + * @return System wide error code. + * @see TVariantHalFunction + */ + virtual TInt VariantHal(TInt aFunction, TAny* a1, TAny* a2); + + /** + * Machine configuration + * @return Pointer to a device configuration information + * @see TTemplateMachineConfig + */ + virtual TPtr8 MachineConfiguration(); + +public: + /** + * external interrupt handling + * These are used to model second-level interrupt controllers at Variant level + * @param anId An interrupt identification number (TTemplateInterruptId enumerated value) + * @param an Isr Address of an Interrupt Service Routine + * @param aPtr Extra parameter to be passed to ISR function + * @return System wide error code + * @see TTemplateInterruptId + */ + + virtual TInt InterruptBind(TInt anId, TIsr anIsr, TAny* aPtr); + virtual TInt InterruptUnbind(TInt anId); + virtual TInt InterruptEnable(TInt anId); + virtual TInt InterruptDisable(TInt anId); + virtual TInt InterruptClear(TInt anId); + + /** + * USB client controller - Some example functions for the case that USB cable detection and + * UDC connect/disconnect functionality are part of the Variant. + * These virtual functions are called by the USB PSL (pa_usbc.cpp). + * If this functionality is part of the ASSP then these functions can be removed as calls to them + * in the PSL will have been replaced by the appropriate internal operations. + */ + virtual TBool UsbClientConnectorDetectable(); + virtual TBool UsbClientConnectorInserted(); + virtual TInt RegisterUsbClientConnectorCallback(TInt (*aCallback)(TAny*), TAny* aPtr); + virtual void UnregisterUsbClientConnectorCallback(); + virtual TBool UsbSoftwareConnectable(); + virtual TInt UsbConnect(); + virtual TInt UsbDisconnect(); + + /** + * miscellaneous if Video buffer is allocated in the main System memory during ASSP/Variant initialisation + * this will return the required size @return Size (in bytes) of required RAM for Video buffer + */ + virtual TInt VideoRamSize(); + + /** + * RAM zone callback functions that will be invoked by the kernel when a RAM zone + * operation should be performed. + */ + static TInt RamZoneCallback(TRamZoneOp aOp, TAny* aId, const TAny* aMasks); + TInt DoRamZoneCallback(TRamZoneOp aOp, TUint aId, const TUint* aMasks); + + IMPORT_C static TUint16 SetSerialNumber( TUint32 aSerialNum ); + IMPORT_C static TUint32 GetSerialNumber( ); + +private: // or public: + static void InitInterrupts(); + static void Spurious(TAny* aId); +public: + // TLinAddr iIdleFunction; // may be used to point to a Bootstrap routine which prepares the CPU to Sleep + static TUint32 HandlerData[3]; + static SInterruptHandler Handlers[ENumXInts]; + TUint32 iSerialNumber; + +private: + static void UsbClientConnectorIsr(TAny *); + +private: + TInt (*iUsbClientConnectorCallback)(TAny*); + TAny* iUsbClientConnectorCallbackArg; + }; + +GLREF_D NE1_TBVariant TheVariant; + +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/inc/variantmediadef.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/inc/variantmediadef.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,98 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\inc\variantmediadef.h +* Media definitions for NE1_TBVariant variant. +* Each Media Driver requires the following definitions +* DRIVECOUNT - The total number of local drive object to be assigned to the Media Driver (1-KMaxLocalDrives) +* DRIVELIST - A list of the local drive numbers (each separated with a comma) to be assigned to the Media Driver. +* Each in the range 0 - (KMaxLocalDrives-1). Total number of drive numbers must equal the value +* of DRIVECOUNT. +* NUMMEDIA - The total number of media objects to be assigned to the Media Driver. +* DRIVENAME - A name for the drive group. +* For the complete set of media definitions +* - The total number of local drive objects assigned should not exceed KMaxLocalDrives. +* - Each Media Driver should be assigned a unique set of drive numbers - no conflicts between Media Drivers. +* - The total number of media objects assigned should not exceed KMaxLocalDrives. +* +*/ + + + +#ifndef __VARIANTMEDIADEF_H__ +#define __VARIANTMEDIADEF_H__ + +// Variant parameters for IRAM Media Driver (MEDINT.PDD) +#define IRAM_DRIVECOUNT 1 +#define IRAM_DRIVELIST 0 +#define IRAM_NUMMEDIA 1 +#define IRAM_DRIVENAME "IRam" + +// Variant parameters for LFFS Media Driver (MEDLFS.PDD) +#define LFFS_DRIVECOUNT 1 +#define LFFS_DRIVELIST 8 +#define LFFS_NUMMEDIA 1 +#define LFFS_DRIVENAME "Flash" + +// Variant parameters for the MMC Controller (EPBUSMMC.DLL) +#define MMC0_DRIVECOUNT 1 +#define MMC0_DRIVELIST 1 +#define MMC0_NUMMEDIA 1 +#define MMC0_DRIVENAME "MultiMediaCard0" + +// Variant parameters for the SDIO Controller (EPBUSSDIO.DLL) +#define SDIO0_DRIVECOUNT 1 +#define SDIO0_DRIVELIST 4 +#define SDIO0_NUMMEDIA 1 +#define SDIO0_DRIVENAME "SecureDiskCard0" + +// Variant parameters for the NAND media driver (MEDNAND.PDD) +#define NAND_DRIVECOUNT 10 +#define NAND_DRIVELIST 2,3,5,6,7,9,10,11,12,13 + +#define NAND_NUMMEDIA 1 +#define NAND_DRIVENAME "Nand" + + +#ifdef __NAND_DEMAND_PAGING__ + +#ifdef __NAND_DATA_PAGING__ + #define PAGING_TYPE DPagingDevice::ERom | DPagingDevice::ECode | DPagingDevice::EData +#else + #define PAGING_TYPE DPagingDevice::ERom | DPagingDevice::ECode +#endif // __NAND_DATA_PAGING__ + +#define NAND_PAGEDRIVELIST 2,3,5,6,7,9,10,11,12,13 // code paging from all drives. +#define NAND_PAGEDRIVECOUNT 10 + + +#define NUM_PAGES 2 // defines the size of fragment +#endif // __DEMAND_PAGING__ + +#define NFE_DRIVECOUNT 3 +#define NFE_DRIVELIST 1 ,2 ,13 +#define NFE_DRIVELETTERLIST 3 ,8 ,-1 // EDRive? IDs of the each instance. (EDriveD,EDriveI,UNMAPPED from estartnandtestpaged.txt) + +#define NFE_PAGEDRIVECOUNT 1 +#define NFE_PAGEDRIVELIST 2 // code paging on first writable partition.in slot #2 + +#define NFE_NUM_PAGES 2 // the number of pages for paging. i.e. the largest block size of any attached media + +#define NFE_INSTANCE_COUNT 2 // the number of NFE media driver instances +#define NFE_INSTANCE_DRIVE_COUNTS 1,2 // the number of drives in NFE_DRIVELIST for each instance of the driver +#define NFE_INSTANCE_PAGEDRIVE_COUNTS 0,1 // the number of drives in NFE_PAGEDRIVELIST for each instance of the driver +#define NFE_INSTANCE_NUM_PAGES 0,4 // the number of pages for each instance of the driver +#define NFE_INSTANCE_PAGING_TYPE 0,DPagingDevice::ECode | DPagingDevice::EData // the paging type for each instance of the driver + +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/key.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/key.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/key.mmp +* ekeyb.dll NE1_TBVariant polled keyboard kernel extension +* +*/ + + + +/** + @file +*/ +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(ekeyb,dll) +targettype kext +romtarget ekeyb.dll + +USERINCLUDE inc +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + + +sourcepath specific +source keyboard.cpp + +library VariantTarget(ecust,lib) + +noexportlibrary +deffile ../../../../os/kernelhwsrv/kernel/eka/~/empty.def + +uid 0x100039cf 0x100000db + +VENDORID 0x70000001 + +capability all diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/key_int.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/key_int.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/key_int.mmp +* ekeyb.dll NE1_TBVariant keyboard library +* +*/ + + + +/** + @file +*/ +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(int_ekeyb,dll) +targettype kext +romtarget int_ekeyb.dll + +USERINCLUDE inc +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + + +sourcepath specific +source keyboard_interrupt.cpp + +library VariantTarget(ecust,lib) + +noexportlibrary +deffile ../../../../os/kernelhwsrv/kernel/eka/~/empty.def + +uid 0x100039cf 0x100000db + +VENDORID 0x70000001 + +capability all diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/keymap.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/keymap.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/keymap.mmp +* ekdata.dll NE1_TBVariant keyboard look-up tables +* +*/ + + + +/** + @file +*/ + + +#include + +target VariantTarget(ekdata,dll) +targettype dll +linkas ekdata.dll + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +sourcepath specific +source keymap.cpp + +library euser.lib + +deffile ../../../../os/kernelhwsrv/kernel/eka/~/ekdata.def + +nostrictdef + +uid 0x1000008d 0x100039e0 + +capability all +vendorid 0x70000001 + +unpagedcode + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/keypad.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/keypad.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Project file for the LCD keypad driver +* +*/ + + + +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "kernel/kern_ext.mmh" + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +USERINCLUDE ../naviengine_assp/lcdgce +USERINCLUDE inc + +target VariantTarget(keypad,dll) +targettype kext +linkas keypad.dll + + +sourcepath specific +source keypad.cpp + +library VariantTarget(power,lib) + +noexportlibrary +//deffile ../../../../os/kernelhwsrv/kernel/eka/~/empty.def + +uid 0x1000008d 0x100039ea +VENDORID 0x70000001 + +capability all + +nostrictdef + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/lcd.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/lcd.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/lcd.mmp +* lcd.dll NE1_TBVariant LCD driver +* +*/ + + + +/** + @file +*/ +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(lcd,dll) +targettype kext +romtarget lcd.dll + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) +SYMBIAN_NE1_TB_SYSTEMINCLUDE(specific) + +sourcepath ../naviengine_assp/lcd +source lcd.cpp + +library VariantTarget(ecust,lib) +library resman.lib + +noexportlibrary +deffile ../../../../os/kernelhwsrv/kernel/eka/~/empty.def + +epocallowdlldata + +uid 0x1000008d 0x100039e8 + +VENDORID 0x70000001 + +capability all + +MACRO CPU_AFFINITY_ANY diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/lcdgce.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/lcdgce.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/lcdgce.mmp +* lcdgce.dll NE1_TBVariant LCD driver +* +*/ + + + +/** + @file +*/ +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(lcdgce,pdd) +targettype pdd + + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) +SYMBIAN_NE1_TB_SYSTEMINCLUDE(specific) +userinclude inc + +sourcepath ../naviengine_assp/lcdgce +source lcdgce.cpp + +library VariantTarget(ecust,lib) +library resman.lib + + +deffile ./~/lcdgcene1_tb.def + +MACRO CPU_AFFINITY_ANY + +epocallowdlldata + + +uid 0x100039d0 0x100039e8 + +VENDORID 0x70000001 + +capability all + +SMPSAFE + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/medlffs.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/medlffs.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/medlffs.mmp +* medlfs.pdd NE1_TBVariant LFFS media physical device driver +* +*/ + + + +/** + @file +*/ + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(medlfs,pdd) +targettype pdd +linkas medlfs.pdd +epocallowdlldata +capability all + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) +SYMBIAN_NE1_TB_SYSTEMINCLUDE(specific) +USERINCLUDE inc + +sourcepath ../../../../os/kernelhwsrv/kernel/eka/drivers/medlfs +source flash_media.cpp + +sourcepath specific +source lffsdev.cpp + +library elocd.lib +library VariantTarget(kanaviengine,lib) +library VariantTarget(ecust,lib) + + +VENDORID 0x70000001 diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/memmodel_bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/memmodel_bld.inf Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,136 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +PRJ_MMPFILES +../../../../os/kernelhwsrv/kernel/eka/kernel/ekern +../../../../os/kernelhwsrv/kernel/eka/kernel/kc_exe +../../../../os/kernelhwsrv/kernel/eka/kernel/exmoncommon + +PRJ_EXTENSIONS + +start extension base/ne1_tb_genbootinc ne1_tb_genbootinc + +#ifdef SYMBIAN_OLD_EXPORT_LOCATION +option INC_PATH $(EPOCROOT)epoc32/include +#else +option INC_PATH $(EPOCROOT)epoc32/include/platform +#endif + +#ifdef SINGLE +option MEMMODEL direct +#elif defined(FLEXIBLE) +option MEMMODEL flexible +#else +option MEMMODEL multiple +#endif + +end + + +PRJ_EXTENSIONS + +#if 0 // #ifdef SBSV2 // If using SBSv2 with bootstrap FLM, MEMMODEL MUST begin with a capital letter + +start extension base.bootstrap bootstrap + +#ifdef SMP +option SMP 1 +#endif + +#ifdef SINGLE +option NAME _sne1_tb_bootrom +option MEMMODEL Direct +#elif defined(FLEXIBLE) +option NAME _fne1_tb_bootrom +option MEMMODEL Flexible +#else +option NAME _ne1_tb_bootrom +option MEMMODEL Multiple +#endif + +option CPU arm +option SOURCES ./bootstrap/ne1_tb.s + +#ifdef SMP +option EXTRA_EPOC32_INC_PATH $(EPOCROOT)epoc32/include/platform/nkernsmp/arm $(EPOCROOT)epoc32/include/platform/assp/naviengine/$(MEMMODEL) +option GENINCLUDES_HEADERS ../../../../os/kernelhwsrv/kernel/eka/include/nkernsmp/arm/arm_gic.h ../../../../kernelhwsrv/kernel/eka/include/kernel/arm/arm_types.h +#else +option EXTRA_EPOC32_INC_PATH $(EPOCROOT)epoc32/include/platform/assp/naviengine/$(MEMMODEL) +option GENINCLUDES_HEADERS ../../../../os/kernelhwsrv/kernel/eka/include/kernel/arm/arm_types.h +#endif + +option EXTRA_SRC_PATH ./bootstrap +#ifdef SINGLE +option INCLUDES ./single/config.inc +#else +option INCLUDES ./config.inc +#endif +option E32PATH ../../../../os/kernelhwsrv/kernel/eka/../. + +end + +#else // !SBSV2 + +start extension base/bootstrap bootstrap + +#ifdef SYMBIAN_OLD_EXPORT_LOCATION +option INC_PATH $(EPOCROOT)epoc32/include +#else +option INC_PATH $(EPOCROOT)epoc32/include/platform +#endif + +#ifdef SMP +option SMP 1 +#endif + + +#ifdef SINGLE +option NAME _sne1_tb_bootrom +option MEMMODEL direct +#elif defined(FLEXIBLE) +option NAME _fne1_tb_bootrom +option MEMMODEL flexible +#else +option NAME _ne1_tb_bootrom +option MEMMODEL multiple +#endif + +option CPU arm +option SOURCES ne1_tb.s + +#ifdef SMP +option EXTRA_INC_PATH $(INC_PATH)/nkernsmp/arm $(INC_PATH)/assp/naviengine/$(MEMMODEL) +option GENINCLUDES arm_gic.inc arm_types.inc +#else +option EXTRA_INC_PATH $(INC_PATH)/assp/naviengine/$(MEMMODEL) +option GENINCLUDES arm_types.inc +#endif + +option EXTRA_SRC_PATH $(EXTENSION_ROOT)/bootstrap +#ifdef SINGLE +option INCLUDES $(EXTENSION_ROOT)/single/config.inc +#else +option INCLUDES $(EXTENSION_ROOT)/config.inc +#endif +option E32PATH $(EXTENSION_ROOT)/../../../../os/kernelhwsrv/kernel/eka/../. + +end + + +#endif // !SBSV2 diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/monitor.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/monitor.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/monitor.mmp +* +*/ + + + +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "../../../../os/kernelhwsrv/kernel/eka/kernel/exmondebug.mmp" + +target VariantTarget(exmondebug,dll) + +userinclude inc +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + +userinclude ../naviengine_assp + +sourcepath specific +source monitor.cpp + +library VariantTarget(ecust,lib) + +noexportlibrary +deffile ../../../../os/kernelhwsrv/kernel/eka/~/empty.def + +VENDORID 0x70000001 + +capability all diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/nand/variant_nand_plat.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/nand/variant_nand_plat.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#ifndef __VARIANT_NAND_PLAT_H__ +#define __VARIANT_NAND_PLAT_H__ + +#include +#include + + +// +// Const declarations +// +const TNandDeviceInfo gDeviceTable[] = { +/********************************************************************************************************/ +// iManufacturerCode; +// | iDeviceCode; +// | | iNumBlocks; +// | | | iNumSectorsPerBlock; +// | | | | iNumBytesMain; +// | | | | | iNumBytesSpare; +// | | | | | | iSectorShift; +// | | | | | | | iBlockShift; +// | | | | | | | | iBlksInRsv; +// | | | | | | | | | iBadPos; +// | | | | | | | | | | iLsnPos; +// | | | | | | | | | | | iECCPos; +// | | | | | | | | | | | | iFlags; +// | | | | | | | | | | | | | +// V V V V V V V V V V V V V +/********************************************************************************************************/ + { ESamsungId, 0xDAu, 2048, 256, 512, 16, 9, 14, 40, 0, 2, 6, TDeviceFlags(ELargeBlock|EDataIoWidth16)}, // 64 MB (512 MBit) + // Last entry + { TManufacturerId(0), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TDeviceFlags(0) } + }; + + + +/** + @internalTechnology +*/ +const TUint32 KCoreldrStackAddr = 0x8C0003FCu; // Top of coreloader stack + +/** + * The following constants support relocation of the NAND FBR for this platform + * KNandFbrSectorOffset is the third of three constants required - it is defined + * in nand_fbr_offset.h + */ +#ifndef MINIBOOT +const TBool KNandMinibootUsed = EFalse; +const TBool KNandCoreldrRelocatable = ETrue; +#else +const TBool KNandMinibootUsed = ETrue; +const TBool KNandCoreldrRelocatable = EFalse; +#endif /* MINIBOOT */ + +#endif // __VARIANT_NAND_PLAT_H__ + + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/nandboot/coreldrasm.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/nandboot/coreldrasm.s Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,320 @@ +; +; Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +; All rights reserved. +; This component and the accompanying materials are made available +; under the terms of "Eclipse Public License v1.0" +; which accompanies this distribution, and is available +; at the URL "http://www.eclipse.org/legal/epl-v10.html". +; +; Initial Contributors: +; Nokia Corporation - initial contribution. +; +; Contributors: +; +; Description: +; ne1_tb\nandboot\coreldrasm.s +; + + INCLUDE armcpudefs.inc ; Constants used by the MMU code + INCLUDE nand_plat.inc ; NAND device specifics + INCLUDE naviengine.inc + + EXPORT BootEntry + EXPORT GetRomTargetAddress + EXPORT GetSMRIBTargetAddress + EXPORT GetSMRTargetStartAddress + EXPORT GetSMRTargetMaxAddress + EXPORT clearRestartTimer + EXPORT RestartAuxiliaryCores + IF USE_MMU + IMPORT setupMMU + EXPORT GetPageTableBaseAddress + EXPORT GetMemoryBankArrayBase + EXPORT GetNumberOfMemoryBankAddresses + ELSE ; USE_MMU + ; NOT using MMU + IMPORT loadmain + EXPORT bootos + ENDIF ; USE_MMU + + EXPORT charout + EXPORT WriteW + +;****************************************************************************** +; Constants + +KHwSDramAddr EQU 0x80000000 +KSDramSizeDdr EQU 0x10000000 ; 256 MBytes + + +KSerial0PhysBase EQU 0x18034000 ; // must be same number as in ne1_tb.s +;Serial Port Register Offsets +Serial_DLL EQU 0 +Serial_DLH EQU 4 +Serial_LCR EQU 0xc +Serial_THR EQU 0 +Serial_LSR EQU 0x14 + +; KRomTargetAddress is the memory location where the core image will be +; placed in RAM. +KRomTargetAddress EQU KHwSDramAddr ; Base of RAM +KSDramTopAddress EQU KHwSDramAddr + KSDramSizeDdr ; 0x90000000 +KSRTargetSize EQU 0x02000000 ; 32 Mb +KSRIBTargetAddress EQU KSDramTopAddress - KSRTargetSize ;0x8E000000 (Top of Ram - 0x02000000 (32 Mb)) +KSRIBTargetSize EQU 0x00001000 ; 4 Kb +KSRTargetStartAddress EQU KSRIBTargetAddress + KSRIBTargetSize ; 0x8E001000 (+4Kb) +KSRTargetMaxAddress EQU KSDramTopAddress + +; define linker area for placement of .text section (LINKBASE) +; also use PRESERVE8 to indicate (to linker) stack 8B alignment + + PRESERVE8 + AREA |Boot$$Code|, CODE, READONLY, ALIGN=6 + +;****************************************************************************** +; Entry point for the Core Loader +; Note that this MUST be at the start of the image!!! +;****************************************************************************** +BootEntry + + LDR r13, =KCoreldrStackAddr ; C code needs a stack + + bl PauseAuxiliaryCores + + ; This hardware reference platorm, NaviEngine, bootstraps the coreloader image from NAND and + ; has just started executing. Most of the hardware setup, such as configuring RAM, has + ; already been done by the bootloader. For systems that boot directly from the coreloader + ; image most of the hardware setup will need to be done here as it won't have been done + ; in bootoader code. + + BL InitUart + + IF USE_MMU + + b setupMMU + +; Store the page tables after the coreloader on the next 128K boundary +KCoreLdrPDEAddress EQU ( ( _LINKBASE_ +0x00020000)) :AND: 0xfff20000 + +; Format of table is, for each mapping region +; virtual address, physical address, length of region (each these must be +; megabyte aligned) the PDEs created will be for 1MB sections and so will cover +; 1MB above the VA+length. +; +; A table with more elements would look like this +; memoryTable DCD virtual_address1, physical_address1, length1 +; DCD virtual_address2, physical_address2, length2 +; DCD virtual_address3, physical_address3, length3 +; +memoryTable DCD KHwSDramAddr, KHwSDramAddr, KSDramSizeDdr; Map all SDRAM + +GetPageTableBaseAddress + LDR r0,=KCoreLdrPDEAddress + __JUMP lr + +GetMemoryBankArrayBase + ADRL r0,memoryTable + __JUMP lr + +GetNumberOfMemoryBankAddresses + MOV r0,#1 ; 1 row only + __JUMP lr + + ELSE ; USE_MMU + ; NOT using MMU + + b loadmain ; jump directly into the NAND core loader without setting up the MMU + +; bootos symbol needs defining if NOT using the MMU code +bootos + + BL RestartAuxiliaryCores + MOV pc, r0 ; jump off to OS + + ENDIF ; USE_MMU + + +GetRomTargetAddress + ldr r0, =KRomTargetAddress + __JUMP lr + +GetSMRIBTargetAddress + ldr r0, =KSRIBTargetAddress + __JUMP lr + +GetSMRTargetStartAddress + ldr r0, =KSRTargetStartAddress + __JUMP lr + +GetSMRTargetMaxAddress + ldr r0, =KSRTargetMaxAddress + __JUMP lr + +;****************************************************************************** +; writes character in r0 to the debug port +;****************************************************************************** +charout + STMFD sp!, {r1,r2,lr} + LDR r1, =KSerial0PhysBase + + ; wait for debug port to be ready for data +1 + LDR r2, [r1, #Serial_LSR] + TST r2, #0x20 + BEQ %BT1 + + ; output character to debug port + STR r0, [r1, #Serial_THR] + + LDMFD sp!, {r1,r2,pc} + +;****************************************************************************** +; Printf("%0x", r0) a word to the serial port (stack required) +; +; Enter with +; r0 = word +; debug port initialised +; +; Leave with +; no registers changed +;****************************************************************************** +WriteW + STMFD sp!, {r0-r4, lr} + MOV r4, #28 + MOV r1, r0 + +1 MOV r0, r1, LSR r4 + AND r0, r0, #0x0000000F + CMP r0, #9 + ADDLE r0, r0, #48 + ADDGT r0, r0, #55 + BL charout + SUBS r4, r4, #4 + BGE %BT1 + + MOV r0, #' ' + BL charout + + LDMFD sp!, {r0-r4, pc} + +;****************************************************************************** +; Prepares and starts a timer +; Preserves all registers +; NOT SUPPORTED ON NAVIENGINE - SUPPLIED TO ALLOW COMPILE +;****************************************************************************** +clearRestartTimer + MOV r0, lr + NOP + MOV pc, r0 + +;****************************************************************************** +; Initialise the serial port (stack required) +; This is derived from the NaviEngine bootstrap's debug uart initialisation code. +; Enter with : +; none +; Leave with : +; no registers changed +;****************************************************************************** +InitUart + MOV r0, lr + LDR r1, =KSerial0PhysBase + + ; set up debug port + MOV r2, #0x83 + STR r2, [r1, #Serial_LCR] + MOV r2, #KBaudRateDiv_default + STR r2, [r1, #Serial_DLL] + MOV r2, #0 + STR r2, [r1, #Serial_DLH] + MOV r2, #0x03 + STR r2, [r1, #Serial_LCR] + + MOV pc, r0 + + + + + +;*************************************************************************************** +; SMP code - PauseAuxiliaryCores +; Expects lr and sp +;*************************************************************************************** +PauseAuxiliaryCores + + + ; IF SMP + + ; Is this the boot processor ? + MRC p15, 0, r0, c0, c0, 5 + ANDS r0, r0, #0x0f ; r0 = CPU number 0-3 + BEQ IsBootProcessor ; Branch out if CPU 0 (= boot processor) + mov r10, r0 + ; No - this is an AP + + mov r5, r13 + add r13, r13, r10, lsl #2 ; Move to stack var for this core + mov r3, #10 + +1 + ldr r4, [r5] ; load message + teq r3,r4 ; is message r3? + streq r3, [r13] ; + addeq r3, r3, #1 + teq r3, #13 + beq Signaled + + nop + nop + nop + nop + + B %BA1 + +Signaled + + ldr pc, =KRomTargetAddress + +IsBootProcessor + add r13, r13, #16 ; reserve space on stack for signaling + mov pc, lr + + + +;*************************************************************************************** +; SMP code - RestartAuxiliaryCores +; Expects lr, r0 - address to start cores at. +; Corrupts r1-3 +;*************************************************************************************** + + +RestartAuxiliaryCores + +;KCoreldrStackAddr EQU 0x8C0003FC + + + ; This code wakes the other cores, causing them to run the image + + LDR r3, =KCoreldrStackAddr ; Find our origanal stack frame + mov r2 , #10 +1 + str r2, [r3] ; send r2 + + ldr r1, [r3, #4] ; read from core 1 + teq r1, r2 ; has it recieved? + bne %BA1 + + ldr r1, [r3, #8] ; read from core 2 + teq r1, r2 ; has it recieved? + bne %BA1 + + ldr r1, [r3, #12] ; read from core 3 + teq r1, r2 ; has it recieved? + bne %BA1 + + add r2,r2, #1 ; add 1 to our massage, and try agian + teq r2, #13 ; we repeat a few times, to make sure + bne %BA1 + + mov pc, lr + + END diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/nandboot/nandtest_load_rel_autoexec.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/nandboot/nandtest_load_rel_autoexec.bat Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,17 @@ +@rem +@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +@rem All rights reserved. +@rem This component and the accompanying materials are made available +@rem under the terms of "Eclipse Public License v1.0" +@rem which accompanies this distribution, and is available +@rem at the URL "http://www.eclipse.org/legal/epl-v10.html". +@rem +@rem Initial Contributors: +@rem Nokia Corporation - initial contribution. +@rem +@rem Contributors: +@rem +@rem Description: +@rem + +nandloader -f -a d: mboot.img cldr.img core.img rofs1.img -r -w \ No newline at end of file diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/nandboot/quicknand.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/nandboot/quicknand.bat Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,18 @@ +@rem +@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +@rem All rights reserved. +@rem This component and the accompanying materials are made available +@rem under the terms of "Eclipse Public License v1.0" +@rem which accompanies this distribution, and is available +@rem at the URL "http://www.eclipse.org/legal/epl-v10.html". +@rem +@rem Initial Contributors: +@rem Nokia Corporation - initial contribution. +@rem +@rem Contributors: +@rem +@rem Description: +@rem + +z: +nandloader -a d: cldr.img core.img rofs1.img -r diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/ne1_tb.oby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/ne1_tb.oby Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#ifndef __NE1_TB_OBY__ +#define __NE1_TB_OBY__ + +define LANGID 01 +define BUILDNO 0 +define VERSION 0.01 + +DEFAULT_LANGUAGE 01 + +REM Definitions specific to NE1_TBVariant + +#undef _ARM4 +#define _ARM4 + +#define __TEMPLATE__ + +define TEMPLATE 0x09080001 +define VARIANT v1 +define VARID TEMPLATE +define ASSP_DIR EPOCROOT##epoc32\release\mtemplate +define ROMMEGS 12 /* !! HEX !! */ +define PLATFORM_NAME template + +#define COLOR + +REM defines for IrDA options +REM Uncomment the line below to enable IrDA to use a Jeteye ESI09680 pod with serial card adapter +REM #define _ENABLE_IRDA_POD_ +REM define which port IrDA uses +define IRPOD_ESK irda_port1.esk + +REM define which serial port Bluetooth protocol uses +define BLUETOOTH_ESK bt_port2.esk + +REM Define whether or not to include USB client support: +#define EUSBC + +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/nktest/hw_init.cia --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/nktest/hw_init.cia Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,89 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\nktest\hw_init.cia +* +*/ + + + +#include +#include +#include + +#ifdef __SMP__ +#include +#endif + + +/****************************************************************************** + * Fast counter + ******************************************************************************/ +extern "C" __NAKED__ TUint64 fast_counter() + { + // Return a 64 bit high resolution timestamp count + // Timer 1 counts from 00000000 to FFFFFEFF and then wraps back to 0 + // Timer 2 counts from 00000000 to FFFFFFFF and then wraps back to 0 + // Both timers increment at 16.667MHz (60ns period) + // Algorithm: + // volatile TUint32 t2 = Timer2Count; // must read t2 first + // volatile TUint32 t1 = Timer1Count; + // TUint32 n = (t1-t2)>>8; // number of times T1 has wrapped + // return t1 + n * 0xFFFFFF00; + + asm("ldr r3, 1f "); // r3 = address of T1 counter + asm("mrs r12, cpsr "); + __ASM_CLI(); // interrupts off + asm("ldr r1, [r3, #0x400] "); // r1 = t2 + asm("ldr r0, [r3] "); // r0 = t1 + asm("msr cpsr, r12 "); // restore interrupts + asm("sub r1, r0, r1 "); // t1-t2 + asm("mov r1, r1, lsr #8 "); // n = (t1-t2)>>8, now have r1:r0 = 2^32*n + t1 + asm("subs r0, r0, r1, lsl #8 "); // subtract 256*n + asm("sbcs r1, r1, #0 "); // propagate borrow + __JUMP(,lr); + + asm("1: "); + asm(".word 0x18036400 "); // address of timer 1 counter + } + +extern "C" __NAKED__ TUint64 fast_counter_x(TUint32*) + { + // Return a 64 bit high resolution timestamp count + // Timer 1 counts from 00000000 to FFFFFEFF and then wraps back to 0 + // Timer 2 counts from 00000000 to FFFFFFFF and then wraps back to 0 + // Both timers increment at 16.667MHz (60ns period) + // Algorithm: + // volatile TUint32 t1 = Timer1Count; + // volatile TUint32 t2 = Timer2Count; + // TUint32 n = (t1-t2)>>8; // number of times T1 has wrapped + // return t1 + n * 0xFFFFFF00; + + asm("ldr r3, 1f "); // r3 = address of T1 counter + asm("mov r2, r0 "); + asm("mrs r12, cpsr "); + __ASM_CLI(); // interrupts off + asm("ldr r1, [r3, #0x400] "); // r1 = t2 + asm("ldr r0, [r3] "); // r0 = t1 + asm("msr cpsr, r12 "); // restore interrupts + asm("stmia r2, {r0,r1} "); + asm("sub r1, r0, r1 "); // t1-t2 + asm("mov r1, r1, lsr #8 "); // n = (t1-t2)>>8, now have r1:r0 = 2^32*n + t1 + asm("subs r0, r0, r1, lsl #8 "); // subtract 256*n + asm("sbcs r1, r1, #0 "); // propagate borrow + __JUMP(,lr); + + asm("1: "); + asm(".word 0x18036400 "); // address of timer 1 counter + } diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/nktest/hw_init.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/nktest/hw_init.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,617 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\nktest\hw_init.cpp +* +*/ + + + +#include +#include +#include +#include "kernboot.h" +//#include + +#ifdef __SMP__ +#include +#endif + + +const TUint KHwBaseMPcorePrivatePhys = 0xC0000000u; + +extern void DumpExcInfo(TArmExcInfo&); +extern void DumpFullRegSet(SFullArmRegSet& a); + +extern "C" void Interrupt_Init1(); +extern "C" void Interrupt_Init2AP(); +extern "C" void Interrupt_Init3(); + +extern "C" TLinAddr DebugPortBase(); + +extern "C" TUint KernCoreStats_EnterIdle(TUint); +extern "C" void KernCoreStats_LeaveIdle(TInt,TUint); + +extern "C" { +extern TLinAddr RomHeaderAddress; +extern TLinAddr SuperPageAddress; +} + +#ifdef __SMP__ +TSpinLock DbgSpinLock(TSpinLock::EOrderGenericIrqLow1); +#endif + + +struct NETimer + { + static inline NETimer& Timer(TUint a) { return *(NETimer*)(0x18036000u + (a<<10)); } + volatile TUint32 iTimerCount; + volatile TUint32 iTimerCtrl; + volatile TUint32 iTimerReset; + volatile TUint32 iGTOPulseStart; + volatile TUint32 iGTOPulseEnd; + volatile TUint32 iGTICtrl; + volatile TUint32 iGTIRisingEdgeCapture; + volatile TUint32 iGTIFallingEdgeCapture; + volatile TUint32 iGTInterrupt; + volatile TUint32 iGTInterruptEnable; + volatile TUint32 iPrescaler; + }; + +class ArmGic + { +public: + static void Dump(); + static void DumpCpuIfc(); + }; + +#ifdef __SMP__ + +extern "C" void ApMainGeneric(volatile SAPBootInfo* aInfo); + +extern "C" { +SVariantInterfaceBlock TheVIB; + +SVariantInterfaceBlock* InitVIB() + { + SVariantInterfaceBlock* v = &TheVIB; + v->iVer = 0; + v->iSize = sizeof(TheVIB); + v->iMaxCpuClock = UI64LIT(400000000); // 400MHz + v->iMaxTimerClock = 200000000u; // 200MHz = CPU CLK / 2 + v->iScuAddr = KHwBaseMPcorePrivatePhys + 0x0; + v->iGicDistAddr = KHwBaseMPcorePrivatePhys + 0x1000; + v->iGicCpuIfcAddr = KHwBaseMPcorePrivatePhys + 0x100; + v->iLocalTimerAddr = KHwBaseMPcorePrivatePhys + 0x600; + return v; + } +} + +#endif + +static TInt SystemTimerInterruptHandle = -1; + +extern "C" { + +void TimerIsr(TAny* aPtr) + { + NETimer& NET = NETimer::Timer(0); + NET.iGTInterrupt = 0x1fu; + __e32_io_completion_barrier(); + ((NTimerQ*)aPtr)->Tick(); + } + +void StartSystemTimer() + { + __KTRACE_OPT(KBOOT,DEBUGPRINT(">StartSystemTimer()")); + + NETimer& NET = NETimer::Timer(0); + NET.iTimerCtrl = 0; + NET.iGTICtrl = 0; + __e32_io_completion_barrier(); + NET.iTimerCtrl = 2; + __e32_io_completion_barrier(); + NET.iTimerReset = 66666; +// NET.iTimerReset = 66666666; + __e32_io_completion_barrier(); + NET.iGTInterrupt = 0x1fu; + __e32_io_completion_barrier(); + + NTimerQ& m=*(NTimerQ*)NTimerQ::TimerAddress(); + TUint32 flags = NKern::EIrqBind_Count; + TInt r = NKern::InterruptBind(36-32, &TimerIsr, &m, flags, 0); + DEBUGPRINT("r=%08x", r); + __NK_ASSERT_ALWAYS(r>=0); + SystemTimerInterruptHandle = r; + + NKern::InterruptEnable(r); + DEBUGPRINT("r=%08x", r); + + NET.iGTInterruptEnable = 0x10u; + __e32_io_completion_barrier(); + NET.iTimerCtrl = 3; + __e32_io_completion_barrier(); + +// NTimerQ& m=*(NTimerQ*)NTimerQ::TimerAddress(); +// TInt r=Interrupt::Bind(EIntIdTimer,&MsTimerTick,&m); +// __NK_ASSERT_ALWAYS(r>=0); +// initTimer(PIT_COUNT_FOR_1MS); +// r=Interrupt::Enable(r); +// KPrintf("r=%d",r); +// __NK_ASSERT_ALWAYS(r>=0); + __KTRACE_OPT(KBOOT,DEBUGPRINT("=0); + SystemTimerInterruptHandle = r; + NKern::InterruptEnable(r); + } + +static int debug_uart_data_available() + { + TUint32 base = DebugPortBase(); + volatile TUint8& LSR = *(volatile TUint8*)(base + 0x14); + return LSR & 0x01; + } + +static int debug_uart_poll() + { + TUint32 base = DebugPortBase(); + volatile TUint8& LSR = *(volatile TUint8*)(base + 0x14); + volatile TUint8& RXHR = *(volatile TUint8*)(base + 0x00); + if (LSR & 0x01) + return RXHR; + return -1; + } + +static void write_debug_uart(char aChar) + { + TUint32 base = DebugPortBase(); + volatile TUint8& LSR = *(volatile TUint8*)(base + 0x14); + volatile TUint8& TXHR = *(volatile TUint8*)(base + 0x00); + + while (!(LSR & 0x20)) + {} + + TXHR = (TUint8)aChar; + } + +const DiagIO DebugUartIO = + { + &debug_uart_data_available, + &debug_uart_poll, + &write_debug_uart + }; + +static void init_debug_uart() + { + write_debug_uart('*'); + TheIoFunctions = &DebugUartIO; + } + +// have DFAR DFSR IFSR R13 R14 CPSR ExcCode R5-R11 R0-R4 R12 PC saved +struct X + { + TUint32 iDFAR; + TUint32 iDFSR; + TUint32 iIFSR; + TUint32 iR13; + TUint32 iR14; + TUint32 iCPSR; + TUint32 iExcCode; + TUint32 iR5; + TUint32 iR6; + TUint32 iR7; + TUint32 iR8; + TUint32 iR9; + TUint32 iR10; + TUint32 iR11; + TUint32 iR0; + TUint32 iR1; + TUint32 iR2; + TUint32 iR3; + TUint32 iR4; + TUint32 iR12; + TUint32 iR15; + }; + +extern "C" { +void hw_init_exc(TUint32* a) + { + X& x = *(X*)a; + TInt irq = DbgSpinLock.LockIrqSave(); + DumpStruct( + "-------------------------------------\n" + "DFAR %w DFSR %w IFSR %w\n" + "R13 %w R14 %w CPSR %w ExcCode %w\n" + "R5 %w R6 %w R7 %w R8 %w\n" + "R9 %w R10 %w R11 %w\n" + "R0 %w R1 %w R2 %w R3 %w\n" + "R4 %w R12 %w PC %w\n", + a); + if (x.iExcCode==2) + { + TUint32* p = (TUint32*)x.iR15; + TUint32 inst = *p; + if (inst>=0xe7ffdef0u && inst<0xe7ffdeffu) + { + PrtHex8(inst); + NewLine(); + x.iR15 += 4; + DbgSpinLock.UnlockIrqRestore(irq); + return; + } + } + RunCrashDebugger(); + } +} + +extern "C" void __DebugMsgGlobalCtor(TUint addr, TUint cpsr) + { + PrtHex8(cpsr); PutSpc(); PrtHex8(addr); NewLine(); + } + +extern "C" TUint64 fast_counter_x(TUint32*); +extern "C" void HwInit0() + { + init_debug_uart(); + + NETimer& T1 = NETimer::Timer(1); + NETimer& T2 = NETimer::Timer(2); + + T1.iTimerCtrl = 0; // stop and reset timer 1 + T1.iGTICtrl = 0; // disable timer 1 capture modes + T2.iTimerCtrl = 0; // stop and reset timer 2 + T2.iGTICtrl = 0; // disable timer 2 capture modes + __e32_io_completion_barrier(); + T1.iPrescaler = 1; // Timer 1 prescaled by 1 (=66.667MHz) + T2.iPrescaler = 1; // Timer 2 prescaled by 1 +// T1.iPrescaler = 4; // Timer 1 prescaled by 4 (=16.667MHz) +// T2.iPrescaler = 4; // Timer 2 prescaled by 4 + __e32_io_completion_barrier(); + T1.iGTInterruptEnable = 0; + T2.iGTInterruptEnable = 0; + __e32_io_completion_barrier(); + T1.iGTInterrupt = 0x1f; + T2.iGTInterrupt = 0x1f; + __e32_io_completion_barrier(); + T1.iTimerCtrl = 2; // deassert reset for timer 1, count still stopped + T2.iTimerCtrl = 2; // deassert reset for timer 2, count still stopped + __e32_io_completion_barrier(); + T1.iTimerReset = 0xfffffeffu; // timer 1 wraps after 2^32-256 counts + T2.iTimerReset = 0xffffffffu; // timer 2 wraps after 2^32 counts + __e32_io_completion_barrier(); + T1.iTimerCtrl = 3; // start timer 1 + __e32_io_completion_barrier(); + T2.iTimerCtrl = 3; // start timer 2 + __e32_io_completion_barrier(); + + // Each time T1 wraps, (T1-T2) increases by 256 after starting at 0 + // t1=T1; t2=T2; n=(t1-t2)>>8; time = t1 + n * (2^32-256) + + TUint32 t[2]; + TUint64 x = fast_counter_x(t); + DEBUGPRINT("t1=%08x t2=%08x result %08x %08x", t[0], t[1], I64HIGH(x), I64LOW(x)); + } + +void Hw_Init1() + { + __CHECKPOINT(); + +#ifdef __SMP__ + NKern::Init0(InitVIB()); +#else + NKern::Init0(0); +#endif + Interrupt_Init1(); + __CHECKPOINT(); + Arm::Init1Interrupts(); + __CHECKPOINT(); + } + +#ifdef __SMP__ +extern "C" void Hw_InitAPs() + { + TSubScheduler& ss = SubScheduler(); + SSuperPageBase& spg = *(SSuperPageBase*)::SuperPageAddress; + TInt ncpus = 4; + TInt cpu; + for (cpu=1; cpu>=6; + return (TInt)aFCdelta; + } +#else +TInt __microseconds_to_timeslice_ticks(TInt us) + { + return (us+999)/1000; + } + +TInt __fast_counter_to_timeslice_ticks(TUint64 aFCdelta) + { + TUint64 fcf = fast_counter_freq(); + TUint64 x = (aFCdelta * 1000 + (fcf - 1)) / fcf; + return (TInt)x; + } +#endif + +extern "C" { +extern TLinAddr RomHeaderAddress; +void __finish() + { + RunCrashDebugger(); + +// TLinAddr f = RomHeaderAddress + 124; +// (*(void (*)(TInt))f)(0x80000000); + + } +} + +extern "C" void NKIdle(TUint32 aStage) + { +/* + SCpuIdleHandler* cih = NKern::CpuIdleHandler(); +#ifdef __SMP__ + TSubScheduler& ss = SubScheduler(); + if (cih && cih->iHandler) + (*cih->iHandler)(cih->iPtr, aStage, ss.iUncached); +#else + if (cih && cih->iHandler) + (*cih->iHandler)(cih->iPtr, aStage); +#endif + else if (K::PowerModel) + K::PowerModel->CpuIdle(); + else + Arm::TheAsic->Idle(); +*/ + __cpu_idle(); + } + + +extern "C" TUint32 IrqDispatch(TUint32 aVector) + { + if (aVector<32 || aVector>127) + { + GIC_CPU_IFC.iEoi = aVector; + *(TInt*)0xdeaddead = 0; + return aVector; + } + NKern::Interrupt(aVector - 32); + return aVector; + } + +const TUint8 IntIsEdge[96] = + { + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + +extern "C" void Interrupt_Init1() + { + __KTRACE_OPT(KBOOT, DEBUGPRINT(">Interrupt_Init1()")); + Arm::SetIrqHandler((TLinAddr)&IrqDispatch); + TInt i; + for (i=32; i<128; ++i) + { + TBool edge = IntIsEdge[i-32]; + TUint32 flags = 0; + if (i>=36 && i<42) + flags |= NKern::EIrqInit_Count; // timers count all interrupts + if (edge) + flags |= NKern::EIrqInit_RisingEdge; + else + flags |= NKern::EIrqInit_LevelHigh; + TInt r = NKern::InterruptInit(i-32, flags, i, i); + __KTRACE_OPT(KBOOT, DEBUGPRINT("InterruptInit %d(%02x) -> %d", i-32, i, r)); + __NK_ASSERT_ALWAYS(r==KErrNone); + } + + __KTRACE_OPT(KBOOT, DEBUGPRINT(" + +extern "C" TLinAddr DebugPortBase() + { + const TRomHeader& romHdr = *(const TRomHeader*)RomHeaderAddress; + if (romHdr.iDebugPort & 1) + return 0x18034400u; + return 0x18034000u; + } + + +extern "C" TUint KernCoreStats_EnterIdle(TUint) + { + return (TUint) EFalse; + } + +extern "C" void KernCoreStats_LeaveIdle(TInt,TUint) + { + } diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/nktest/interrupts.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/nktest/interrupts.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\nktest\interrupts.cpp +* NaviEngine interrupt control and dispatch +* +*/ + + + +#if 0 +#include +#include +#include + +#undef EXPORT_C +#define EXPORT_C /* */ + +extern "C" void CheckPoint(); + +#define __CHECKPOINT() CheckPoint() + +#include "../specific/interrupts.cpp" +#include "../specific/ioapic.cpp" + +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/nktest/nktest.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/nktest/nktest.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/nktest/nktest.mmp +* +*/ + + + +#define STANDALONE_NANOKERNEL +macro __STANDALONE_NANOKERNEL__ + +#include + +target VariantTarget(nktest,exe) +targettype exe + +#ifdef SMP +#include +#else +#include +#endif + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) +SYMBIAN_NE1_TB_SYSTEMINCLUDE(specific) +USERINCLUDE ../inc +USERINCLUDE . +SYMBIAN_BASE_SYSTEMINCLUDE(kernel) +SYMBIAN_BASE_SYSTEMINCLUDE(nktest) + +firstlib VariantTarget(nk_exe,lib) + +sourcepath . +source hw_init.cpp interrupts.cpp +source hw_init.cia + +#if 0 +sourcepath ../specific +source interrupts.cia pic.cia debuguart.cia timer.cia +source timer.cpp +#endif + +staticlibrary VariantTarget(nkern,lib) +staticlibrary VariantTarget(nktest_lib,lib) + +epocstacksize 0x1000 + +// uids +#ifdef SMP +uid 0x1000008b 0x10287037 +#else +uid 0x1000008b 0x100041af +#endif +vendorid 0x70000001 + +noexportlibrary +linkas nktest.exe + +capability all + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/power.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/power.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/power.mmp +* +*/ + + + +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(power,dll) +targettype kext +linkas power.dll +romtarget power.dll + + +// uncomment the line below to remove any reference to the idlehandler PIL +// this disables power managent +//#define NO_IDLE_HANDLER_PIL +#ifdef NO_IDLE_HANDLER_PIL +macro __NO_IDLE_HANDLER_PIL__ +#endif + +USERINCLUDE inc +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) +SYMBIAN_NE1_TB_SYSTEMINCLUDE(specific) + + +#if defined(SMP) && !defined(NO_IDLE_HANDLER_PIL) +USERINCLUDE ../../../../os/kernelhwsrv/kernel/eka/include/drivers/smppower/sample_idlehandler +#endif + +sourcepath ../../../../os/kernelhwsrv/kernel/eka/drivers/power/binary +source bpower.cpp + +sourcepath specific +source power.cpp power.cia + +#if defined(SMP) && !defined(NO_IDLE_HANDLER_PIL) +staticlibrary idlehelper.lib +staticlibrary sample_smpidlehandler.lib +#endif + +library VariantTarget(ecust,lib) + +deffile ./~/power.def +nostrictdef + +epocallowdlldata + +uid 0x1000008d 0x100039e8 +VENDORID 0x70000001 + +capability all +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/rebootdrv.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/rebootdrv.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* bsp/hwip_nec_naviengine/ne1_tb/rebootdrv.mmp +* reboot.ldd Reboot LDD facility for NaviEngine +* +*/ + + + +/** + @file +*/ + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(reboot,ldd) +targettype ldd +linkas rebootdrv.ldd + +USERINCLUDE inc +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) +USERINCLUDE ../../../../os/kernelhwsrv/kerneltest/e32utils/nandboot/mednand/generic + +sourcepath rebootdrv +source rebootdrv.cpp + +capability all + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/rebootdrv/rebootdrv.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/rebootdrv/rebootdrv.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,139 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* bsp\hwip_nec_naviengine\ne1_tb\rebootdrv.cpp +* +*/ + + + +#ifndef NAVIREBOOT_H +#define NAVIREBOOT_H +#include +#include +#include +#endif //NAVIREBBOT_H + +/** + * Class Constructor + */ +DLddDeviceReboot::DLddDeviceReboot() + { + iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); + //No units, no info, no PDD + } + +/** + * Implementatin of Create method of DLogicalDevice + */ +TInt DLddDeviceReboot::Create(DLogicalChannelBase*& aChannel) + { + aChannel=new DLddReboot; + return aChannel?KErrNone:KErrNoMemory; + } + +/** + * Implementatin of Install method of DLogicalDevice + */ +TInt DLddDeviceReboot::Install() + { + return SetName(&KRebootLddName); + } + +/** + * Implementatin of GetCaps method of DLogicalDevice + */ +void DLddDeviceReboot::GetCaps(TDes8 &aDes) const + { + TCapsRebootV1 b; + b.version=iVersion; + aDes.FillZ(aDes.MaxLength()); + aDes.Copy((TUint8 *)&b,Min(aDes.MaxLength(),sizeof(b))); + } + +/** + * Class Constructor + */ +DLddReboot::DLddReboot() + { + // we are in client's thread context, let's make sure that it knows about us + iClient=&Kern::CurrentThread(); + ((DObject*)iClient)->Open(); + } + +/** + * Class Destructor + */ +DLddReboot::~DLddReboot() + { + Kern::SafeClose((DObject*&)iClient, NULL); + } + +/** + * Implementation of GetCaps method of DLogicalChannelBase + */ + +TInt DLddReboot::Request(TInt aReqNo,TAny* a1,TAny* a2) + { + // we are in client's thread context, let's make sure we aren't + // killed or suspended + NKern::ThreadEnterCS(); + + switch (aReqNo) + { + case RReboot::EReboot: + { + TNandMediaInfo mediaInfo; + NKern::ThreadLeaveCS(); // leave CS as getting mediaInfo may kill us + kumemget(&mediaInfo,a1,sizeof(mediaInfo)); + NKern::ThreadEnterCS(); + (void)Reboot(mediaInfo); + } + break; + case RReboot::EGenericReboot: + { + (void)GenericReboot(); + } + default: + break; + } + + NKern::ThreadLeaveCS(); // unnecessary we should be dead by now... + return KErrNone; + } + +TInt DLddReboot::Reboot(TNandMediaInfo& /*aNandMediaInfo*/) + { + // indicate to boot loader that NAND mini boot routine is required + Kern::Restart(TInt(KtRestartReasonNANDImage )); + return KErrNone; + } + + +TInt DLddReboot::GenericReboot() + { + Kern::Restart(KtRestartReasonHardRestart); + return KErrNone; + } + +/* + * LDD Entry point + */ +DECLARE_STANDARD_LDD() + { + return new DLddDeviceReboot; + } + +// @} + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/replacement_utils/common.cia --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/replacement_utils/common.cia Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\replacement_utils\common.cia +* +*/ + + + +#include +#include +#include +#include + +#if defined(__MEM_MACHINE_CODED__) + +#ifdef USE_REPLACEMENT_MEMSET + +extern "C" EXPORT_C __NAKED__ TAny* memclr(TAny* /*aTrg*/, unsigned int /*aLength*/) + { + KMEMCLRHOOK + // TO DO (optional): Implement replacement memclr + } + +extern "C" EXPORT_C __NAKED__ TAny* memset(TAny* /*aTrg*/, TInt /*aValue*/, unsigned int /*aLength*/) + { + KMEMSETHOOK + // TO DO (optional): Implement replacement memset + } + +#endif // USE_REPLACEMENT_MEMSET + +#ifdef USE_REPLACEMENT_MEMCPY + +extern "C" EXPORT_C __NAKED__ TAny* wordmove(TAny* /*aTrg*/, const TAny* /*aSrc*/, unsigned int /*aLength*/) + { + // TO DO (optional): Implement replacement wordmove + } + +extern "C" EXPORT_C __NAKED__ TAny* memmove(TAny* /*aTrg*/, const TAny* /*aSrc*/, unsigned int /*aLength*/) + { + KMEMMOVEHOOK + // TO DO (optional): Implement replacement memmove + } + +extern "C" EXPORT_C __NAKED__ TAny* memcpy(TAny* /*aTrg*/, const TAny* /*aSrc*/, unsigned int /*aLength*/) + { + KMEMCPYHOOK + // TO DO (optional): Implement replacement memcpy + } + +#endif // USE_REPLACEMENT_MEMCPY + +#endif // __MEM_MACHINE_CODED__ diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/replacement_utils/kernel.cia --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/replacement_utils/kernel.cia Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\replacement_utils\kernel.cia +* +*/ + + + +#include +#include +#include + +#ifdef USE_REPLACEMENT_UMEMGET + +EXPORT_C __NAKED__ void kumemget32(TAny* /*aKernAddr*/, const TAny* /*aAddr*/, TInt /*aLength*/) + { + // TO DO (optional): Implement replacement kumemget32 + } + +EXPORT_C __NAKED__ void umemget32(TAny* /*aKernAddr*/, const TAny* /*aUserAddr*/, TInt /*aLength*/) + { + // TO DO (optional): Implement replacement umemget32 + } + +EXPORT_C __NAKED__ void kumemget(TAny* /*aKernAddr*/, const TAny* /*aAddr*/, TInt /*aLength*/) + { + // TO DO (optional): Implement replacement kumemget + } + +EXPORT_C __NAKED__ void umemget(TAny* /*aKernAddr*/, const TAny* /*aUserAddr*/, TInt /*aLength*/) + { + // TO DO (optional): Implement replacement umemget + } + +#endif // USE_REPLACEMENT_UMEMGET + +#ifdef USE_REPLACEMENT_UMEMPUT + +EXPORT_C __NAKED__ void kumemput32(TAny* /*aAddr*/, const TAny* /*aKernAddr*/, TInt /*aLength*/) + { + // TO DO (optional): Implement replacement kumemput32 + } + +EXPORT_C __NAKED__ void umemput32(TAny* /*aUserAddr*/, const TAny* /*aKernAddr*/, TInt /*aLength*/) + { + // TO DO (optional): Implement replacement umemput32 + } + +EXPORT_C __NAKED__ void kumemput(TAny* /*aAddr*/, const TAny* /*aKernAddr*/, TInt /*aLength*/) + { + // TO DO (optional): Implement replacement kumemput + } + +EXPORT_C __NAKED__ void umemput(TAny* /*aUserAddr*/, const TAny* /*aKernAddr*/, TInt /*aLength*/) + { + // TO DO (optional): Implement replacement umemput + } + +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/replacement_utils/replacement_utils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/replacement_utils/replacement_utils.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\replacement_utils\replacement_utils.h +* This header file controls which of the generic utility functions are replaced +* by the variant. The replacement implmenetations are supplied in the files +* kernel.cia and common.cia in this directory. +* The replacement functions are selected by a series of macros as described +* below: +* Macro: Functions replaced: Location of replacement: +* USE_REPLACEMENT_MEMSET memclr common.cia +* memset +* USE_REPLACEMENT_MEMCPY wordmove common.cia +* memmove +* memcpy +* USE_REPLACEMENT_UMEMGET kumemget32 kernel.cia +* umemget32 +* kumemget +* umemget +* USE_REPLACEMENT_UMEMPUT kumemput32 kernel.cia +* umemput32 +* kumemput +* umemput +* +*/ + + + +#ifndef __REPLACEMENT_UTILS_H__ + +//#define USE_REPLACEMENT_MEMSET +//#define USE_REPLACEMENT_MEMCPY +//#define USE_REPLACEMENT_UMEMGET +//#define USE_REPLACEMENT_UMEMPUT + +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/resmanpsl.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/resmanpsl.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/resmanpsl.mmp +* +*/ + + + +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(resmanpsl,pdd) +targettype kext +linkas resman.pdd + +staticlibrary resmanpsl.lib + +USERINCLUDE inc +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +sourcepath ./specific/ +source resmanpsl.cpp powerresources.cpp + +// all exported APIs +sourcepath ../../../../os/kernelhwsrv/kernel/eka/drivers/resourceman +source resourceman.cpp resource.cpp rescontrol_export.cpp + + +deffile ../../../../os/kernelhwsrv/kernel/eka/~/resman.def + +nostrictdef +noexportlibrary + +library VariantTarget(ecust,lib) + +uid 0x1000008d 0x10285812 + +epocallowdlldata + +capability all + +macro CPU_AFFINITY_ANY +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/rom/base_ne1_tb.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/rom/base_ne1_tb.iby Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,198 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\rom\base_ne1_tb.iby +* +*/ + + + +#define HEAPMAX(x) +#define FIXED + +#if (defined(CRAZYSCHEDDELAY) || defined(CRAZYSCHEDPRIO)) && defined(SMP) +#error The crazy scheduler cannot be used with SMP! +#endif + +#ifdef CRAZYSCHEDDELAY +kerneltrace 0x80000000 0 0x20 +#else +kerneltrace 0x80000000 +#endif +#ifdef CRAZYSCHEDPRIO +CRAZYSCHEDULING(on) +#endif + +#if defined(SMPCOMPATMODE) && defined(SMPCOMPATCPU0) +#error "Can't have SMPCOMPATMODE and SMPCOMPATCPU0 at once!" +#endif +#ifdef SMPCOMPATMODE +SMPUNSAFECOMPAT(on) +#endif +#ifdef SMPCOMPATCPU0 +SMPUNSAFECPU0(on) +#endif +#ifndef SMPUNLOCKTHREADSCORE0 +SMPLOCKKERNELTHREADSCPU0(on) +#endif + +#ifdef WITH_FLEXIBLE_MM +memmodel flexible 0x100000 0x1000 -0x4000 +dlldatatop 0x7f000000 +#else +memmodel multiple 0x100000 +#endif + +multikernel + +#ifdef DEBUGPORT +debugport DEBUGPORT +#else +debugport 0 +#endif + +bootbinary=KERNEL_DIR\_MEMMODEL_PLATFORM_NAME_bootrom.bin + +romlinearbase=0x80000000 +romalign=0x10 +kerneldataaddress=0xC8000000 +kernelheapmin=0x1000 // calculated at boot time +kernelheapmax=0x00FFF000 +dataaddress=0x400000 +defaultstackreserve=0x200000 +romchecksum=0x12345678 + +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_kanaviengine.dll \sys\bin\kanaviengine.dll +#if defined(CRAZYSCHEDDELAY) || defined(CRAZYSCHEDPRIO) +primary[VARID] =KERNEL_DIR\udeb\_MEMMODEL_PLATFORM_NAME_ekern.exe \sys\bin\ekern.exe +#else +primary[VARID] =KERNEL_DIR\DEBUG_DIR\_MEMMODEL_PLATFORM_NAME_ekern.exe \sys\bin\ekern.exe +#endif +variant[VARID] =KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_ecust.dll \sys\bin\ecust.dll +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_hcr.dll \sys\bin\hcr.dll +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_watchdog.dll \sys\bin\watchdog.dll +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_MEMMODEL_PLATFORM_NAME_exmoncommon.dll \sys\bin\exmoncommon.dll +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_exmondebug.dll \sys\bin\exmondebug.dll +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_power.dll \sys\bin\power.dll +#ifdef SYMBIAN_USE_DMA_V2 +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_dma_v2.dll \sys\bin\dma.dll +#else +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_dma.dll \sys\bin\dma.dll +#endif + +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_lcdgce.PDD \sys\bin\DISPLAY0.PDD +device[VARID] =KERNEL_DIR\DEBUG_DIR\display.ldd \sys\bin\DISPLAY0.LDD +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_vserialkeyb.dll \sys\bin\ekeyb.dll +//extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_ekeyb.dll \sys\bin\ekeyb.dll +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_exyin.dll \sys\bin\exyin.dll +device[VARID] =KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_euart.pdd \sys\bin\euart1.pdd // not EUART.PDD, unlike text shell ROMs +#ifdef SYMBIAN_USE_DMA_V2 +device[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_soundsc_v2.pdd \sys\bin\soundsc.pdd +#else +device[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_soundsc.pdd \sys\bin\soundsc.pdd +#endif +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_gpio.dll \sys\bin\gpio.dll +#ifdef HAS_ETHERNET +device[VARID]=KERNEL_DIR\DEBUG_DIR\enet.ldd \sys\bin\enet.ldd +device[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_ethernet.pdd \sys\bin\ethernet.pdd +#endif +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_keypad.dll \sys\bin\keypad.dll +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_i2s.dll \sys\bin\i2s.dll +extension[VARID]=KERNEL_DIR\DEBUG_DIR\elocd.ldd \sys\bin\elocd.ldd +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_medint.pdd \sys\bin\medint.pdd +//extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_epbus.dll \sys\bin\epbus.dll +//extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_epbusv.dll \sys\bin\epbusv.dll +//extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_medlfs.pdd \sys\bin\medlfs.pdd +//device[VARID] =KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_medata.pdd \sys\bin\medata.pdd +device[VARID] =KERNEL_DIR\DEBUG_DIR\ecomm.ldd \sys\bin\ecomm.ldd +device[VARID] =KERNEL_DIR\DEBUG_DIR\esoundsc.ldd \sys\bin\esoundsc.ldd +device[VARID] =KERNEL_DIR\DEBUG_DIR\pipelib.ldd \sys\bin\pipelib.ldd +device[VARID] =KERNEL_DIR\DEBUG_DIR\minkda.ldd \sys\bin\minkda.ldd +extension[VARID]=KERNEL_DIR\DEBUG_DIR\exstart.dll \sys\bin\exstart.dll +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_resmanpsl.PDD \sys\bin\resman.pdd +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_PCI.DLL \sys\bin\pci.dll +extension[VARID]=KERNEL_DIR\DEBUG_DIR\IIC.DLL \sys\bin\IIC.dll +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_CSI.dll \sys\bin\CSI.dll +#ifndef INST_ARM4 +extension[VARID]=KERNEL_DIR\DEBUG_DIR\evfp.dll \sys\bin\evfp.dll +#endif + +// Rom paging config +#ifdef PAGED_ROM +pagedrom +compress +#endif + +#ifdef BTRACE +#define BTRACE_INCLUDED +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_btracex.ldd \sys\bin\btracex.ldd +file=ABI_DIR\DEBUG_DIR\btracec.dll \sys\bin\btracec.dll +#endif +define BTRACEX_LDD _PLATFORM_NAME_btracex.ldd + +#ifdef ENABLE_RESTRICTED_CODE +// USB Drivers +#ifndef __USB + REM Feature USB is not included in this ROM +#elif defined(SYMBIAN_ENABLE_USB_OTG_HOST) && defined(SYMBIAN_INCLUDE_USB_OTG_HOST) +extension[VARID]= KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_USBCC.DLL \Sys\Bin\USBCC.DLL +#else + REM USB has neither been explicitely included nor excluded +#endif +#endif // ENABLE_RESTRICTED_CODE + +//#endif // __USB + +#ifdef ENABLE_RESTRICTED_CODE +//SD Media Driver +#ifdef SYMBIAN_USE_DMA_V2 +extension[VARID]= KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_epbussdiov_v2.dll \sys\bin\mmc.dll +#else +extension[VARID]= KERNEL_DIR\DEBUG_DIR\_PLATFORM_NAME_epbussdiov.dll \sys\bin\mmc.dll +#endif +extension[VARID]= KERNEL_DIR\DEBUG_DIR\epbussd.dll \sys\bin\epbusm.dll +extension[VARID]= KERNEL_DIR\DEBUG_DIR\medsd.pdd \sys\bin\medmmc.pdd +#endif // ENABLE_RESTRICTED_CODE + +#if defined(_NAND2) +#ifdef WITH_FLEXIBLE_MM +#include "../fne1_tb/base_ne1nand2.iby" +#else +#include "../ne1_tb/base_ne1nand2.iby" +#endif + +#else +data=EPOCROOT##epoc32\rom\##VARIANT##\estarttechview.txt \sys\data\estart.txt +#endif + +// Use correct euser +#ifdef SMP +#define EUSER_DLL euser_v6k_smp.dll +#else +#define EUSER_DLL euser_v6k.dll +#endif + +define HAL_DLL _PLATFORM_NAME_hal.dll +define ESTART_EXE _PLATFORM_NAME_e32strt.exe +define KEYMAP_FILE _PLATFORM_NAME_ekdata + +#if !defined(SYMBIAN_GRAPHICS_USE_GCE) +define SCDV_DLL _omapqvga_scdv.dll +#else +#ifdef __TEXTSHELL_OBY__ +define SCDV_DLL _omapqvga_scdv.dll +#else +define SCDV_DLL _generic_scdv.dll +#endif +#endif //!SYMBIAN_GRAPHICS_USE_GCE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/rom/header.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/rom/header.iby Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,205 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* boardsupport/naviengine/navienginebsp/ne1_tb/rom/header.iby +* TO DO: (mandatory) +* This file provides the ROM header information for your variant +* +*/ + +#define USE_CUSTOM_MMC_PARTITION + +#if defined(XABI_ARM4SMP) || defined(XABI_ARMV5SMP) || defined(XABI_ARMV6SMP) || defined(XABI_ARMV7SMP) +#define SMP +#endif + +#define VARIANT_PATH ../adapt/naviengine.nec/navienginebsp/ne1_tb + +#define HEAPMAX(x) + +// +// The Variant ID +// +#define VARID 0x09080001 +#define MAGIC 0x09080001 +#define ALL 0x09080001 +#define FIXED + +#ifdef WITH_DIRECT_MM +// Direct MM + +#define MEMMODEL_VARIANT S##VARIANT## + +kerneltrace 0x80000000 + +memmodel direct 0x1000 + +trace 0x10 +multikernel + +nowrapper + +version=0.01 +bootbinary=\Epoc32\Release\##KMAIN##\_sne1_tb_bootrom.bin + +#ifdef DEBUGPORT +debugport DEBUGPORT +#else +debugport 0 +#endif + +romsize=0x2000000 +romlinearbase=0x88000000 +romalign=0x1000 + +#ifdef SMP +kerneldataaddress=0x70014000 +#else +kerneldataaddress=0x70005000 +#endif + +#ifdef NKERN_ONLY_ROM +dataaddress=0xD0000000 // not used +kernelheapmin=0x00B00000 // must have max=min +kernelheapmax=0x00B00000 +#else +dataaddress=0x71000000 +kernelheapmin=0x100000 // must have max=min +kernelheapmax=0x100000 +#endif + +defaultstackreserve=0x200000 +romchecksum=0x12345678 + +//#define WITH_LFFS +//#define WITH_EXTENSION +//#define WITH_ROFS +//#define WITH_COMP +//#define NAVIENGINE_USE_VGA + +#undef __USB +#define USE_CUSTOM_MMC_PARTITION + +#ifdef UNICODE +unicode +#endif + +#else +// Flexible or Multiple MM + +#if (defined(CRAZYSCHEDDELAY) || defined(CRAZYSCHEDPRIO)) && defined(SMP) +#error The crazy scheduler cannot be used with SMP! +#endif + +#include +#ifdef CRAZYSCHEDDELAY +kerneltrace 0x80000000 0 0x20 +#else +kerneltrace 0x80000000 +#endif +#ifdef CRAZYSCHEDPRIO +CRAZYSCHEDULING(on) +#endif + +#ifdef SMP +#if defined(SMPCOMPATMODE) && defined(SMPCOMPATCPU0) +#error "Can't have SMPCOMPATMODE and SMPCOMPATCPU0 at once!" +#endif +#ifdef SMPCOMPATMODE +SMPUNSAFECOMPAT(on) +#endif +#ifdef SMPCOMPATCPU0 +SMPUNSAFECPU0(on) +#endif +#ifdef SMPCRAZYINTS +CRAZYINTERRUPTS(on) +#endif +#ifndef SMPUNLOCKTHREADSCORE0 +SMPLOCKKERNELTHREADSCPU0(on) +#endif +#endif //SMP + +#ifdef WITH_FLEXIBLE_MM +memmodel flexible 0x100000 0x1000 -0x4000 +dlldatatop 0x7f000000 +#define MEMMODEL_VARIANT F##VARIANT## +bootbinary=\Epoc32\Release\##KMAIN##\_fne1_tb_bootrom.bin +#else +memmodel multiple 0x100000 +#define MEMMODEL_VARIANT VARIANT +bootbinary=\Epoc32\Release\##MAIN##\_ne1_tb_bootrom.bin +#endif + +trace 0x10 +collapse arm gcc 0 +multikernel + +nowrapper + +version=0.01 + +#ifdef DEBUGPORT +debugport DEBUGPORT +#else +debugport 0 +#endif + +#ifdef UBOOTLDR_ROM + +// for Bootloader remove components not required +#undef __USB +#define SYMBIAN_EXCLUDE_RUNTESTS + +#endif + +romsize=0x2000000 +romlinearbase=0x80000000 +romalign=0x10 +kerneldataaddress=0xC8000000 +kernelheapmin=0x1000 // calculated at boot time +kernelheapmax=0x00FFF000 +dataaddress=0x400000 +defaultstackreserve=0x200000 +romchecksum=0x12345678 + +//#define WITH_LFFS +//#define WITH_EXTENSION +//#define WITH_ROFS +//#define WITH_COMP +//#define NAVIENGINE_USE_VGA + +#ifdef UNICODE +unicode +#endif + +#if defined(_NAND2) || defined(_NANDTEST2) +// Pick up ROFS components +#define WITH_ROFS +#define LARGE_BLOCK +#define MULTIPLEROFS +#endif + +// Pick up the composite filesystem if NAND is required +#if defined(_NAND) || defined(_NAND2) || defined(_NANDTEST2) || defined(_NANDTEST) +#define WITH_COMP // Include ecomp.fsy +#endif + +#define CUSTOM_ESTART + +#ifndef INST_ARM4 +// Enable VFP +#define VFPHELPERS +#endif + +#endif \ No newline at end of file diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/rom/kernel.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/rom/kernel.iby Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,244 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\rom\kernel.iby +* TO DO: (mandatory) +* This file includes all the kernel files for your base port +* Important: 'extension' libraries are started at boot time in the order specified +* in this file, ensure dependencies are considered. +* +*/ + + +#if defined(PAGED_ROM) || defined(PAGED_CODE) +#if !defined(_NAND2) && !defined(_NANDTEST2) && !defined(MMC_PAGED_ROM) +#error Demand paging on h4hrp requires nand2 or mmc support +#endif +#endif + +// Rom paging config +#ifdef PAGED_ROM +pagedrom +compress +#endif + +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_KANAVIENGINE.DLL \sys\bin\kanaviengine.dll +primary[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##MEMMODEL_VARIANT##_EKERN.EXE \sys\bin\ekern.exe +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_BTRACEX.LDD \sys\bin\btracex.ldd +variant[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_ECUST.DLL \sys\bin\ecust.dll +#ifndef WITH_DIRECT_MM +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_HCR.DLL \sys\bin\hcr.dll +#else +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_WATCHDOG.DLL \sys\bin\watchdog.dll +#endif +//extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_SERIALNO.DLL \sys\bin\serialno.dll +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##MEMMODEL_VARIANT##_EXMONCOMMON.DLL \sys\bin\exmoncommon.dll + +#ifdef CRASH_LOG_NAND2 +extension[VARID]= \epoc32\release\##KMAIN##\##BUILD##\_##VARIANT##_exmonlognand.dll \sys\bin\exmonlog.dll +#endif + +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_EXMONDEBUG.DLL \sys\bin\exmondebug.dll + +#ifndef WITH_DIRECT_MM +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_POWER.DLL \sys\bin\power.dll +#ifdef SYMBIAN_USE_DMA_V2 +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_DMA_V2.DLL \sys\bin\DMA.DLL +#else +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_DMA.DLL \sys\bin\DMA.DLL +#endif +#endif + +// In the initial phases of development, when neither display and keyboard drivers are available +// you may want to use the VT100 Sreen Driver (which also keyboard input and keyboard translation). +// In that case just include the following line: +#ifdef NAVIENGINE_USE_VT100 +#define EDISP_DRV \EDISP_VT100.DLL +#else +#undef EDISP_DRV +#endif + +#if !defined(EDISP_DRV) +extension[MAGIC]=\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_lcdgce.PDD \sys\bin\DISPLAY0.PDD +#if defined(SYMBIAN_BASE_USE_GCE) || defined(SYMBIAN_GRAPHICS_USE_GCE) +device[MAGIC]=\Epoc32\Release\##KMAIN##\##BUILD##\display.ldd \sys\bin\DISPLAY0.LDD +#endif +#ifdef UBOOTLDR_ROM +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_UBOOTLDRKEYB.DLL \sys\bin\ekeyb.dll +#else +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_VSERIALKEYB.DLL \sys\bin\ekeyb.dll +#endif +#endif + +//extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_EKEYB.DLL \sys\bin\ekeyb.dll +file[VARID]= \Epoc32\Release\##MAIN##\##BUILD##\_##VARIANT##_EKDATA.DLL \sys\bin\ekdata.dll + +device[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_EUART.PDD \sys\bin\euart.pdd + +#ifndef WITH_DIRECT_MM +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_GPIO.DLL \sys\bin\gpio.dll +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_EXYIN.DLL \sys\bin\exyin.dll +device[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\ENET.LDD \sys\bin\enet.ldd +device[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_ETHERNET.PDD \sys\bin\ethernet.pdd +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_KEYPAD.DLL \sys\bin\keypad.dll +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_I2S.DLL \sys\bin\i2s.dll +#endif + +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\ELOCD.LDD \sys\bin\elocd.ldd +#if !defined(WITH_DIRECT_MM) && !defined(INST_ARM4) +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\EVFP.DLL \sys\bin\evfp.dll +#endif +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_MEDINT.PDD \sys\bin\medint.pdd + +// ne1_tb estart file +#ifndef WITH_DIRECT_MM +file=\Epoc32\Release\##MAIN##\##BUILD##\_##VARIANT##_e32strt.exe sys\bin\estart.exe HEAPMAX(0x2000) +#endif + +//Adding Unistore2 XSR NAND support to the NaviEngine hardware platform +#if defined(_NAND2) || defined(_NANDTEST2) +device[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_REBOOT.LDD \Sys\Bin\REBOOT.LDD +#include "ne1nand2.iby" +#elif !defined(WITH_DIRECT_MM) +data=\epoc32\rom\##VARIANT##\estart.txt \Sys\Data\ESTART.TXT +#endif + +// //extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_EPBUS.DLL \sys\bin\epbus.dll +// //extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_EPBUSV.DLL \sys\bin\epbusv.dll +// //extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_MEDLFS.PDD \sys\bin\medlfs.pdd +// //device[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_MEDATA.PDD \sys\bin\medata.pdd + +device[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\ECOMM.LDD \sys\bin\ecomm.ldd +device[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\PIPELIB.LDD \sys\bin\pipelib.ldd +device[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\ESOUNDSC.LDD \sys\bin\esoundsc.ldd +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\EXSTART.DLL \sys\bin\exstart.dll +extension[VARID] = \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_RESMANPSL.PDD \sys\bin\resman.pdd +#ifndef WITH_DIRECT_MM +extension[VARID] = \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_PCI.DLL \sys\bin\pci.dll +#endif + +#ifndef WITH_DIRECT_MM +#ifdef CSI_STANDALONE_CHANNEL + +#ifdef CSITESTS_INCLUDED +device[VARID]=\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_d_csi_ctrless.ldd \sys\bin\d_csi.ldd +#endif + +#else // CONTROLLER-present + +extension[VARID]=\Epoc32\Release\##KMAIN##\##BUILD##\IIC.DLL \sys\bin\iic.dll +extension[VARID]=\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_CSI.dll \sys\bin\csi.dll + +#ifdef SYMBIAN_USE_DMA_V2 +device[VARID]=\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_SOUNDSC_V2.PDD \sys\bin\soundsc.pdd +#else +device[VARID]=\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_SOUNDSC.PDD \sys\bin\soundsc.pdd +#endif + +#ifdef CSITESTS_INCLUDED +device[VARID]=\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_d_csi.ldd \sys\bin\d_csi.ldd +#endif + +#endif // CSI_STANDALONE_CHANNEL +#endif // WITH_DIRECT_MM + +#if defined(PCI_TEST) +extension[VARID] = \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_PCI-test.DLL \sys\bin\pci-test.dll +#endif + +#ifdef ENABLE_RESTRICTED_CODE +// USB Client +//device[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\USBC.LDD \sys\bin\EUSBC.LDD +// USB Device Driver +//extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_USBCC.DLL \sys\bin\USBCC.DLL + +#ifndef __USB +REM Feature USB is not included in this ROM +#else +#ifdef SYMBIAN_ENABLE_USB_OTG_HOST +#include +#endif // SYMBIAN_ENABLE_USB_OTG_HOST + +// USB Device Driver +// USB LDD +// (The target file name has to be lower case, for otherwise it collides with the macro 'EUSBC'!) +device[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\USBC.LDD \Sys\Bin\eusbc.ldd +#ifdef USE_HSUSB +// USB external transceiver driver +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_FIBULA.DLL \Sys\Bin\FIBULA.DLL +#else +// USB PDD +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_USBCC.DLL \sys\bin\USBCC.DLL +#endif // USE_HSUSB, SYMBIAN_ENABLE_USB_OTG_HOST +#endif // __USB + +//SD Media Driver +#ifndef WITH_DIRECT_MM +#ifdef MMC_PAGED_ROM +#ifdef SYMBIAN_USE_DMA_V2 +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_EPBUSSDIOVDP_V2.DLL \sys\bin\MMC.DLL +#else +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_EPBUSSDIOVDP.DLL \sys\bin\MMC.DLL +#endif +#else +#ifdef SYMBIAN_USE_DMA_V2 +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_EPBUSSDIOV_V2.DLL \sys\bin\MMC.DLL +#else +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_EPBUSSDIOV.DLL \sys\bin\MMC.DLL +#endif +#endif +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\EPBUSSD.DLL \sys\bin\EPBUSM.DLL +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\MEDSD.PDD \sys\bin\MEDMMC.PDD +#if defined(USE_NFE) +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_medtestnfe.pdd \Sys\Bin\medtestnfe.pdd +#endif +#endif // WITH_DIRECT_MM +#endif // ENABLE_RESTRICTED_CODE + +// Use correct euser +#ifdef SMP +#define EUSER_DLL euser_v6k_smp.dll +// allow to specify maximum number of CPU cores used in system +#ifdef SMP_NUM_CPUS +patchdata ekern.exe @ KSMPNumCpus ##SMP_NUM_CPUS## +#endif +#else +#define EUSER_DLL euser_v6k.dll +#endif + +#ifdef E32TESTS_INCLUDED +// Include optional test drivers for e32test +#ifndef WITH_DIRECT_MM +#ifdef SYMBIAN_USE_DMA_V2 +device[VARID]= \epoc32\release\##KMAIN##\##BUILD##\d_dma2.ldd \sys\bin\d_dma2.ldd +device[VARID]= \epoc32\release\##KMAIN##\##BUILD##\d_dma_compat.ldd \sys\bin\d_dma_compat.ldd +#else +device[VARID]= \epoc32\release\##KMAIN##\##BUILD##\d_dma.ldd \sys\bin\d_dma.ldd +device[VARID]= \epoc32\release\##KMAIN##\##BUILD##\d_dma2_compat.ldd \sys\bin\d_dma2_compat.ldd +#endif // SYMBIAN_USE_DMA_V2 +#endif // WITH_DIRECT_MM + +#ifdef ENABLE_RESTRICTED_CODE +device[VARID]= \epoc32\release\##KMAIN##\##BUILD##\d_medch.ldd \sys\bin\d_medch.ldd +#endif // ENABLE_RESTRICTED_CODE + +// this CSI_CTRLESS.dll should be included because of some dependency problems found in BTB, +// that autotest picks up d_csi_ctrless.ldd automatically, which needs this dll in the rom. +extension[VARID]=\Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_CSI_CTRLESS.dll \sys\bin\_##VARIANT##_csi_ctrless.dll +#endif // E32TESTS_INCLUDED + +#ifdef CSITESTS_INCLUDED +// Include optional test drivers for csi +file=\Epoc32\Release\##KMAIN##\##BUILD##\t_csi.exe \sys\bin\t_csi.exe +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/rom/naviengine.oby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/rom/naviengine.oby Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,92 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#ifndef __NAVIENGINE_OBY__ +#define __NAVIENGINE_OBY__ + +// Generate final built ROM name and ROM image version +define LANGID 01 +define BUILDNO 0 +define VERSION 0.01 + +#define _ARMV5 + +// Pull in variant specific base kernel files +#define __NE1_TB__ + +//#define WITH_FLEXIBLE_MM + +#ifdef SMP +// Use SMP-enabled kernel +#define _KABI armv5smp +#if !defined WITH_FLEXIBLE_MM +// SMP on ARM requires Flexible Memory Model +#define WITH_FLEXIBLE_MM +#endif +// allow to specify maximum number of CPU cores used in system +#ifdef SMP_NUM_CPUS +patchdata ekern.exe @ KSMPNumCpus SMP_NUM_CPUS +#endif +#endif + +// NB! Don't change VARID: bootstrap hardcodes matching ID pattern +define VARID 0x09080001 +define VARIANT NE1_TB +define ROMMEGS 40 /* !! HEX !! */ +#ifdef WITH_FLEXIBLE_MM +define MEMMODEL_PLATFORM_NAME FNE1_TB +#else +define MEMMODEL_PLATFORM_NAME NE1_TB +#endif +define PLATFORM_NAME NE1_TB + +// Use colour resources +#define COLOR + +REM defines for IrDA options +REM Uncomment the line below to enable IrDA to use a Jeteye ESI09680 pod with serial card adapter +REM #define _ENABLE_IRDA_POD_ +REM define which port IrDA uses +define IRPOD_ESK irda_port2.esk + +// Pull in network support for Ethernet +#define HAS_ETHERNET + +#ifdef ENABLE_RESTRICTED_CODE +// Pull in USB +#define EUSBC + +#if !defined (USE_SD_MMC) && !defined (USE_SDIO_SD_MMC) +#define USE_MMC +#endif + +REM Pick up NAND2 components if the ROM is built with -D _NAND2 +#ifdef _NAND2 +#define WITH_NAND2 +#endif +#endif // ENABLE_RESTRICTED_CODE + +//#define WITH_LFFS + +#ifndef INST_ARM4 +// Enable VFP +#define VFPHELPERS +#endif + +#endif // __NAVIENGINE_OBY__ diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/rom/ne1usbhost.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/rom/ne1usbhost.iby Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#ifdef ENABLE_RESTRICTED_CODE +#ifdef SYMBIAN_INCLUDE_USB_OTG_HOST +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_usbhost.dll \Sys\Bin\usbhost.dll +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\usbhubdriver.ldd \Sys\Bin\usbhubdriver.ldd +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\usbdi.ldd \Sys\Bin\usbdi.ldd +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\otgdi.ldd \Sys\Bin\otgdi.ldd +#endif +#endif // ENABLE_RESTRICTED_CODE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/sdcontroller.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/sdcontroller.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#define BLD_MMC_SD + +// Enable DMA support in build time +macro DMA_SUPPORTED + +SMPSAFE + +#include +#include "kernel/kern_ext.mmh" + +targettype kext +romtarget epbusv.dll + +USERINCLUDE ../../../../os/kernelhwsrv/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c + +USERINCLUDE ../../../../os/kernelhwsrv/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c/sdio + +USERINCLUDE inc + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) +SYMBIAN_NE1_TB_SYSTEMINCLUDE(specific) + + +USERINCLUDE ../naviengine_assp/mmc/inc +USERINCLUDE ../naviengine_assp/mmc/angelus25 +USERINCLUDE ../naviengine_assp/mmc/sdcard3c +userinclude ../naviengine_assp/mmc/angelus25 + +sourcepath ../naviengine_assp/mmc/sdcard3c +source mmcstack.cpp +source mmcdma.cpp +source sdhw.cpp +source mmcpsu.cpp +source sd_init.cpp + +sourcepath ../naviengine_assp/mmc/angelus25 +source angelus25.cpp + + +library VariantTarget(kanaviengine,lib) +library VariantTarget(ecust,lib) + +library dma.lib +library resman.lib + +macro MMC_SD +// SMP Driver Testing +macro CPU_AFFINITY_ANY + +library epbussd.lib + +epocallowdlldata + +capability all + +target VariantTarget(epbussdiov,dll) + +VENDORID 0x70000001 + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/sdcontroller_v2.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/sdcontroller_v2.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#define BLD_MMC_SD + +// Enable DMA support in build time +macro DMA_SUPPORTED + +SMPSAFE + +#include +#include "kernel/kern_ext.mmh" + +targettype kext +romtarget epbusv.dll + +USERINCLUDE ../../../../os/kernelhwsrv/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c + +USERINCLUDE ../../../../os/kernelhwsrv/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c/sdio + +USERINCLUDE inc + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) +SYMBIAN_NE1_TB_SYSTEMINCLUDE(specific) + + +USERINCLUDE ../naviengine_assp/mmc/inc +USERINCLUDE ../naviengine_assp/mmc/angelus25 +USERINCLUDE ../naviengine_assp/mmc/sdcard3c +userinclude ../naviengine_assp/mmc/angelus25 + +sourcepath ../naviengine_assp/mmc/sdcard3c +source mmcstack.cpp +source mmcdma.cpp +source sdhw.cpp +source mmcpsu.cpp +source sd_init.cpp + +sourcepath ../naviengine_assp/mmc/angelus25 +source angelus25.cpp + + +library VariantTarget(kanaviengine,lib) +library VariantTarget(ecust,lib) + +library dma2.lib +library resman.lib + +macro MMC_SD +// SMP Driver Testing +macro CPU_AFFINITY_ANY + +library epbussd.lib + +epocallowdlldata + +capability all + +target VariantTarget(epbussdiov_v2,dll) + +VENDORID 0x70000001 + +SMPSAFE + +MACRO DMA_APIV2 diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/sdcontrollerdp.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/sdcontrollerdp.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Builds SD controller with Demand Paging Enabled +* +*/ + + + + +#define BLD_MMC_SD +// Enable DMA support in build time +macro DMA_SUPPORTED +macro __MMC_DEMAND_PAGING__ +// SMP Driver Testing +macro CPU_AFFINITY_ANY + +#include +#include "kernel/kern_ext.mmh" + +targettype kext +romtarget epbusvdp.dll + +USERINCLUDE ../../../../os/kernelhwsrv/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c + +USERINCLUDE ../../../../os/kernelhwsrv/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c/sdio + +USERINCLUDE inc + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) +SYMBIAN_NE1_TB_SYSTEMINCLUDE(specific) + + +USERINCLUDE ../naviengine_assp/mmc/inc +USERINCLUDE ../naviengine_assp/mmc/angelus25 +USERINCLUDE ../naviengine_assp/mmc/sdcard3c +userinclude ../naviengine_assp/mmc/angelus25 + +sourcepath ../naviengine_assp/mmc/sdcard3c +source mmcstack.cpp +source mmcdma.cpp +source sdhw.cpp +source mmcpsu.cpp +source sd_init.cpp + +sourcepath ../naviengine_assp/mmc/angelus25 +source angelus25.cpp + + +library VariantTarget(kanaviengine,lib) +library VariantTarget(ecust,lib) + +library dma.lib +library resman.lib + +macro MMC_SD +library epbussd.lib + +epocallowdlldata + +capability all + +target VariantTarget(epbussdiovdp,dll) + +VENDORID 0x70000001 + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/sdcontrollerdp_v2.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/sdcontrollerdp_v2.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Builds SD controller with Demand Paging Enabled +* +*/ + + + + +#define BLD_MMC_SD +// Enable DMA support in build time +macro DMA_SUPPORTED +macro __MMC_DEMAND_PAGING__ +// SMP Driver Testing +macro CPU_AFFINITY_ANY + +#include +#include "kernel/kern_ext.mmh" + +targettype kext +romtarget epbusvdp.dll + +USERINCLUDE ../../../../os/kernelhwsrv/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c + +USERINCLUDE ../../../../os/kernelhwsrv/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c/sdio + +USERINCLUDE inc + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) +SYMBIAN_NE1_TB_SYSTEMINCLUDE(specific) + + +USERINCLUDE ../naviengine_assp/mmc/inc +USERINCLUDE ../naviengine_assp/mmc/angelus25 +USERINCLUDE ../naviengine_assp/mmc/sdcard3c +userinclude ../naviengine_assp/mmc/angelus25 + +sourcepath ../naviengine_assp/mmc/sdcard3c +source mmcstack.cpp +source mmcdma.cpp +source sdhw.cpp +source mmcpsu.cpp +source sd_init.cpp + +sourcepath ../naviengine_assp/mmc/angelus25 +source angelus25.cpp + + +library VariantTarget(kanaviengine,lib) +library VariantTarget(ecust,lib) + +library dma2.lib +library resman.lib +macro MMC_SD +library epbussd.lib + +epocallowdlldata + +capability all + +target VariantTarget(epbussdiovdp_v2,dll) + +VENDORID 0x70000001 + +SMPSAFE + +MACRO DMA_APIV2 diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/serialno.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/serialno.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include +#include "kernel/kern_ext.mmh" + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) +SYMBIAN_NE1_TB_SYSTEMINCLUDE(specific) +USERINCLUDE inc + +targettype kext +linkas serialno.dll +target VariantTarget(serialno,dll) + +sourcepath serialno +source serialno.cpp + +library VariantTarget(kanaviengine,lib) +library VariantTarget(ecust,lib) + +epocallowdlldata +uid 0x1000008d 0x100039e5 +capability all +VENDORID 0x70000001 + +SMPSAFE \ No newline at end of file diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/serialno/serialno.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/serialno/serialno.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* @file +* @brief determine board serial number. +* This code is intended to read the board serial number and set it in the +* variant config for later retrieval via HAL. +* Currently, on NaviEngine, the Ethernet driver will set the HAL serial number +* to the lowest 4 bytes of the MAC address, so this is a stub DLL for now. +* +*/ + + + +#include +#include "variant.h" + +/** + * DLL entry point function. + */ +DECLARE_STANDARD_EXTENSION() + { + __KTRACE_OPT(KEXTENSION, Kern::Printf("SerialNo: setting board's serial number")); + return NE1_TBVariant::SetSerialNumber(0); + } diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/single/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/single/bld.inf Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +PRJ_PLATFORMS +ARM4 ARMV5 +ARM4SMP ARMV5SMP + + +#define SINGLE +#define NO_GCCXML +#include "..//memmodel_bld.inf" diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/single/config.inc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/single/config.inc Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,171 @@ +; +; Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +; All rights reserved. +; This component and the accompanying materials are made available +; under the terms of "Eclipse Public License v1.0" +; which accompanies this distribution, and is available +; at the URL "http://www.eclipse.org/legal/epl-v10.html". +; +; Initial Contributors: +; Nokia Corporation - initial contribution. +; +; Contributors: +; +; Description: +; +; NE1_TBVariant bootstrap configuration file + +; Include to enable tracing +; GBLL CFG_DebugBootRom + +; Include to initialise debug port in bootstrap without enabling bootstrap +; trace. Useful for __EARLY_DEBUG__ mode. +; GBLL CFG_InitDebugPort + +; Include one of these to select the CPU + GBLL CFG_CPU_ARM11MP + +; Include the following line if this is a bootloader bootstrap +; GBLL CFG_BootLoader + +; If you want to supply a custom set of initial vectors (including reset vector) include the following line +; GBLL CFG_CustomVectors +; +; and provide a custom_vectors.inc file + +; Variant Number + INIT_NUMERIC_CONSTANT CFG_HWVD, 0x09080001 + +; Include the following line if default memory mapping should use shared memory. +; Should be defined on multicore (SMP) devices. + GBLL CFG_USE_SHARED_MEMORY + +; On ARM architecture 6 processors, include the following line to override the threshold +; on total physical RAM size at which the multiple memory model switches into large address space mode +; i.e. size>threshold -> 2Gb per process, size<=threshold -> 1Gb per process +; Defaults to 32Mb. +; INIT_NUMERIC_CONSTANT CFG_ARMV6_LARGE_CONFIG_THRESHOLD, + +; For the direct memory model only, include the following line if you wish the exception vectors at the +; start of the bootstrap to be used at all times. This is only relevant if an MMU is present - this option +; is mandatory if not. +; GBLL CFG_UseBootstrapVectors +; +; If the above option is in use (including if no MMU is present) the following symbol should be defined +; to specify the offset from the bootstrap to the kernel image. + INIT_NUMERIC_CONSTANT KernelCodeOffset, 0x4000 + +; Include the following line if you wish to include the ROM autodetection code based on data bus +; capacitance and image repeats. +; GBLL CFG_AutoDetectROM + +; Include the following line to minimise the initial kernel heap size +; On the direct memory model the size of the kernel data area (super page to end of kernel heap) +; is rounded up to the next 1Mb if this is not included, 4K if it is. +; On the moving and multiple models, the size of the initial kernel heap area is rounded up to +; the next 64K if this is not included, 4K if it is. +; GBLL CFG_MinimiseKernelHeap + +; On the moving or multiple memory models, include either or both of the following lines to +; specify the size of the initial kernel heap +; INIT_NUMERIC_CONSTANT CFG_KernelHeapMultiplier, +; INIT_NUMERIC_CONSTANT CFG_KernelHeapBaseSize, +; +; The initial kernel heap size is MAX( + * N / 16, value specified in ROMBUILD ) +; where N is the total physical RAM size in pages. +; defaults to 24K and defaults to 9*16 (ie 9 bytes per page). + +; Uncomment if using ARM1136 processor and ARM1136 Erratum 353494 +; "Rare conditions can cause corruption of the Instruction Cache" +; is fixed on this hardware. +; +; NOTE: The boot table should use this macro to determine whether RONO or RORO permissions +; are used for the exception vectors. If the erratum is not fixed, RORO must be used. +; +; GBLL CFG_CPU_ARM1136_ERRATUM_353494_FIXED + +; Uncomment if using ARM1136 processor and ARM1136 Erratum 364296 +; "Possible Cache Data Corruption with Hit-Under-Miss" +; is fixed on this hardware. +; +; GBLL CFG_CPU_ARM1136_ERRATUM_364296_FIXED + +; Uncomment if using ARM1136 processor and ARM1136 Erratum 399234 +; "Write back data cache entry evicted by write through entry causes data corruption" +; is fixed on this hardware. +; Workaround +; The erratum may be avoided by marking all cacheable memory as one of write through or write back. +; This requires the memory attributes described in the translation tables to be modified by software +; appropriately, or the use of the remapping capability to remap write through regions to non cacheable. +; +; If this macro is enabled, it should be accompanied by: +; "#define __CPU_ARM1136_ERRATUM_399234_FIXED" in variant.mmh +; GBLL CFG_CPU_ARM1136_ERRATUM_399234_FIXED + + +; Uncomment if: +; 1) using ARM1136 processor and ARM1136 Erratum 411920: "Invalidate Entire Instruction Cache +; operation might fail to invalidate some lines if coincident with linefill" +; is fixed on this hardware, or +; 2) using ARM1176 processor and ARM1176 Erratum 415045: "Invalidate Entire Instruction Cache +; operation might fail to invalidate some lines if coincident with linefill +; is fixed on this hardware. +; Workaround: +; 1) Disables the use of of prefetch range cache operations by setting RV bit in Auxiliary Ctrl Reg. +; 2) Replaces Invalidate ICache operation with the sequence defined in the errata document. +; If this macro is enabled, it should be accompanied by: +; "#define __CPU_ARM1136_ERRATUM_411920_FIXED" in variant.mmh +; +; GBLL CFG_CPU_ARM1136_ERRATUM_411920_FIXED + + +; Uncomment if using ARM1136 processor and ARM1136 Erratum 415662: "Invalidate Instruction Cache by +; Index might corrupt cache when used with background prefetch range" is fixed on this hardware. +; Workaround: +; Disables the use of of prefetch range cache operations by setting RV bit in Auxiliary Ctrl Reg. +; +; GBLL CFG_CPU_ARM1136_ERRATUM_415662_FIXED + + +; Uncomment if this variant config needs to support the Shadow Memory Regions +; (SMR) feature in the kernel. Basically allows media based images to be copied +; into memory which is later reserved by the Kernel RAM Allocator. +; One user of the SMR feature is the HCR component when used with media based +; setting repository. Thus variant configs that support the new MHA HCR +; component and expect media based settings must define this macro e.g. NAND +; Core Image ROM, but not BootLoader ROM etc. +; +; GBLL CFG_ENABLE_SMR_SUPPORT + + INIT_NUMERIC_CONSTANT KTTBRExtraBits, 0x02 + + +; These are deduced from the supplied configuration +; CFG_ARMV6 +; CFG_MMUPresent +; CFG_CachePresent +; CFG_WriteBufferPresent +; CFG_SplitCache +; CFG_SplitTLB +; CFG_AltDCachePresent +; CFG_WriteBackCache +; CFG_CacheWriteAllocate +; CFG_CachePhysicalTag +; CFG_CacheFlushByDataRead +; CFG_CacheFlushByWaySetIndex +; CFG_CacheFlushByLineAlloc +; CFG_CachePolicyInPTE +; CFG_TEX +; CFG_SingleEntryDCacheFlush +; CFG_SingleEntryICacheFlush +; CFG_SingleEntryITLBFlush +; CFG_SingleEntryTLBFlush +; CFG_CacheTypeReg +; CFG_BTBPresent +; CFG_CARPresent +; CFG_PrefetchBuffer +; CFG_FCSE_Present +; CFG_ASID_Present +; CFG_IncludeRAMAllocator + + END diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/single/nktest.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/single/nktest.iby Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +primary[MAGIC]=\Epoc32\Release\##KMAIN##\##BUILD##\_sne1_tb_nktest.exe \nktest.exe +variant[MAGIC]=\Epoc32\Release\##KMAIN##\##BUILD##\_sne1_tb_nktest.exe \ecust.dll + + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/single/variant.mmh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/single/variant.mmh Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,143 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +// +// TO DO: (mandatory) +// +// Add here a definition for your CPU (list in CONFIG.INC) +// +macro __CPU_ARM11MP__ +// +// TO DO: (mandatory) +// +// Add here a definition for your Memory Model +// +#define MM_DIRECT +#ifdef STANDALONE_NANOKERNEL +macro __MEMMODEL_DIRECT__ +#endif +// +// TO DO: (mandatory) +// +// Macro which generates the names for the binaries for this platform +// +#ifndef VariantTarget +#define VariantTarget(name,ext) _sne1_tb_##name##.##ext +#endif + +#ifndef VariantMediaDefIncludePath +#define VariantMediaDefIncludePath SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ne1_tb) +#endif + +// Used in MMP files for include paths e.g. to hcrconfig.h header and others +#ifndef VariantIncludePath +#define VariantIncludePath SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) +#endif + +#ifndef AsspIncludePath +#define AsspIncludePath SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +#endif + +//Include debug support +macro __DEBUGGER_SUPPORT__ + +// +// TO DO: +// +// If euser is built from the variant, uncomment the following line to build it +// as ARM rather than Thumb +// +//#define __BUILD_VARIANT_EUSER_AS_ARM__ +// +// TO DO: (optional) +// +// To replace some of the generic utility functions with variant specific +// versions (eg to replace memcpy with a version optimised for the hardware), +// uncomment the two lines below and edit the files in the replacementUtils +// directory. +// +//#define REPLACE_GENERIC_UTILS +//#define VariantReplacementUtilsPath ne1_tb/replacement_utils +// +// TO DO: (optional) +// +// Enable BTrace support in release versions of the kernel by adding +// the following BTRACE macro declarations +// +macro BTRACE_KERNEL_ALL +// +// TO DO: +// +// Uncomment the following line if using the r1p0 release or later of the ARM1136 processor. +// +//#define __CPU_ARM1136_IS_R1__ +// + +// Include the following line if default memory mapping should use shared memory. +// Should be on for multicore (SMP) devices. + +macro __CPU_USE_SHARED_MEMORY + + +// TO DO: +// +// Uncomment the next line if using the ARM1136 processor and ARM1136 Erratum 406973 +// "CLREX instruction might be ignored during data cache line fill" +// is fixed on this hardware. +// +//#define __CPU_ARM1136_ERRATUM_406973_FIXED + +// Uncomment next line if using the ARM1136 processor and ARM1136 Erratum 408022 +// "Cancelled write to CONTEXTID register might update ASID" +// is fixed on this hardware. +// +//#define __CPU_ARM1136_ERRATUM_408022_FIXED + + +// Uncomment if: +// 1) using ARM1136 processor and ARM1136 Erratum 411920: "Invalidate Entire Instruction Cache +// operation might fail to invalidate some lines if coincident with linefill" +// is fixed on this hardware, or +// 2) using ARM1176 processor and ARM1176 Erratum 415045: "Invalidate Entire Instruction Cache +// operation might fail to invalidate some lines if coincident with linefill +// is fixed on this hardware. +// Workaround: +// 1) Disables the use of of prefetch range cache operations by setting RV bit in Auxiliary Ctrl Reg. +// 2) Replaces Invalidate ICache operation with the sequence defined in the errata document. +// If this macro is enabled, it should be accompanied by: +// "GBLL CFG_CPU_ARM1136_ERRATUM_411920_FIXED" in variant.mmh +// +// #define __CPU_ARM1136_ERRATUM_411920_FIXED + +macro FAULTY_NONSHARED_DEVICE_MEMORY + +// SMP Timestamp uses inline code from BSP +macro __NKERN_TIMESTAMP_USE_INLINE_BSP_CODE__ +#define AsspNKernIncludePath SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/nkern) + +// FIQ can not be disabled on naviengine, tell kernel to ignore it... +macro __FIQ_IS_UNCONTROLLED__ + +macro MONITOR_THREAD_CPU_TIME + +#if defined(__USING_USING_ASSP_REGISTER_API__) || defined(__USING_INTERRUPT_API__) || defined(__USING_ASSP_REGISTER_API__) +library VariantTarget(kanaviengine,lib) +#endif + +// Include GPIO STATIC EXTENSION +macro __USE_GPIO_STATIC_EXTENSION__ + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/soundsc.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/soundsc.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,72 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/soundscne1_tb.mmp +* soundsc.pdd NE1_TBVariant shared chunk sound PDD +* +*/ + + + +/** + @file +*/ +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(soundsc,pdd) +targettype pdd +romtarget soundsc.pdd + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) +SYMBIAN_NE1_TB_SYSTEMINCLUDE(specific) +USERINCLUDE ../../../../os/kernelhwsrv/kernel/eka/drivers/iic +USERINCLUDE inc + +#ifdef SMP +SYMBIAN_BASE_SYSTEMINCLUDE(nkernsmp) +#else +SYMBIAN_BASE_SYSTEMINCLUDE(nkern) +#endif + + +//the sound driver +sourcepath soundsc +source soundsc.cpp +source soundsc_channel.cpp + +//the codec +sourcepath specific +source cs42l51.cpp + +library dma.lib +library VariantTarget(i2s,lib) +library VariantTarget(ecust,lib) +library VariantTarget(gpio,lib) +library iic.lib +uid 0x100039d0 0x1000015c +VENDORID 0x70000001 + +capability all +EPOCALLOWDLLDATA + +MACRO CPU_AFFINITY_ANY + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/soundsc/soundsc.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/soundsc/soundsc.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,171 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* \bsp\hwip_nec_naviengine\ne1_tb\soundsc\sound.cpp +* Implementation of a sound physical device driver (PDD) factory +* +*/ + + + +#include "soundsc_plat.h" +#include +#include + +_LIT(KSoundScPddName,"SoundSc.NE1_TBVariant"); + +// Definitions for the kernel thread created for this sound driver. +_LIT(KSoundScDriverThreadName,"SoundDriverThread"); +const TInt KSoundScDriverThreadPriority=26; // One less than DFC thread 0 (26) + +/** +Define a function at ordinal 0 which returns a new instance of a DPhysicalDevice-derived factory class. +*/ +DECLARE_STANDARD_PDD() + { + return new DSoundScPddNE1_TB; + } + +/** +Constructor for the shared chunk sound PDD factory class. +*/ +DSoundScPddNE1_TB::DSoundScPddNE1_TB() + { + __KTRACE_SND(Kern::Printf(">DSoundScPddNE1_TB::DSoundScPddNE1_TB")); + + // Support units KSoundScTxUnit0 & KSoundScRxUnit0. + iUnitsMask=(1<DSoundScPddNE1_TB::~DSoundScPddNE1_TB")); + + // Destroy the kernel thread. + if (iDfcQ) + { + iDfcQ->Destroy(); + } + } + +/** +Second stage constructor for the shared chunk sound PDD factory class. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DSoundScPddNE1_TB::Install() + { + __KTRACE_SND(Kern::Printf(">DSoundScPddNE1_TB::Install")); + TInt r = KErrNone; + if (!iDfcQ) + { + // Create a new sound driver DFC queue (and associated kernel thread). + r = Kern::DynamicDfcQCreate(iDfcQ, KSoundScDriverThreadPriority, KSoundScDriverThreadName); + if (r != KErrNone) + { + return r; + } + } + +#ifdef CPU_AFFINITY_ANY + NKern::ThreadSetCpuAffinity((NThread*)(iDfcQ->iThread), KCpuAffinityAny); +#endif + + r = SetName(&KSoundScPddName); // Set the name of the driver object + + return(r); + } + +/** +Returns the PDD's capabilities. This is not used by the Symbian OS device driver framework +or by the LDD. +@param aDes A descriptor to write capabilities information into +*/ +void DSoundScPddNE1_TB::GetCaps(TDes8& /*aDes*/) const + {} + +/** +Called by the kernel's device driver framework to check if this PDD is suitable for use +with a logical channel. +This is called in the context of the client thread which requested the creation of a logical +channel - through a call to RBusLogicalChannel::DoCreate(). +The thread is in a critical section. +@param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate(). +@param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate() - not used. +@param aVer The version number of the logical channel which will use this physical channel. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DSoundScPddNE1_TB::Validate(TInt aUnit, const TDesC8* /*aInfo*/, const TVersion& aVer) + { + // Check that the version specified is compatible. + if (!Kern::QueryVersionSupported(RSoundSc::VersionRequired(), aVer)) + { + return(KErrNotSupported); + } + + // Check the unit number is compatible + if (aUnit!=KSoundScTxUnit0 && aUnit!=KSoundScRxUnit0) + { + return(KErrNotSupported); + } + + return(KErrNone); + } + +/** +Called by the kernel's device driver framework to create a physical channel object. +This is called in the context of the client thread which requested the creation of a logical +channel - through a call to RBusLogicalChannel::DoCreate(). +The thread is in a critical section. +@param aChannel Set by this function to point to the created physical channel object. +@param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate(). +@param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate(). +@param aVer The version number of the logical channel which will use this physical channel. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DSoundScPddNE1_TB::Create(DBase*& aChannel, TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& /*aVer*/) + { + __KTRACE_SND(Kern::Printf(">DSoundScPddNE1_TB::Create")); + + TInt r = KErrNone; + + // Create the appropriate PDD channel object. + DNE1_TBSoundScPddChannel* pD = NULL; + + if (aUnit==KSoundScRxUnit0) + { + // Create a record PDD channel object + pD = new DNE1_TBSoundScPddChannel(ESoundDirRecord); + } + else + { + // Create a playback PDD channel object + pD = new DNE1_TBSoundScPddChannel(ESoundDirPlayback); + } + + r = KErrNoMemory; + if (pD) + { + pD->iPhysicalDevice = this; + r = pD->DoCreate(); + aChannel = pD; + } + return(r); + } diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/soundsc/soundsc_channel.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/soundsc/soundsc_channel.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,756 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* \bsp\hwip_nec_naviengine\ne1_tb\soundsc\soundsc_channel.cpp +* Implementation of the NE1_TBVariant playback and record shared chunk sound physical device driver (PDD). +* This file is part of the NE1_TBVariant Base port +* Unit is identified by the time of its creation by the DSoundScPddNE1_TB - by specifying TSoundDirection +* (either ESoundDirRecord or ESoundDirPlayback) as the constructor parameter. +* +*/ + + + +/** + @file +*/ +#include +#include +#include +#include "soundsc_plat.h" + +#if _DEBUG +static const char KSoundPDDPanicCat[] = "SOUNDSC PDD, line:"; +#endif + +// physical address of the I2S channel 0 Tx register +const TUint32 KHwI2S0TxPhys = KHwI2S0Phys + KHoI2STx; + +// physical address of the I2S channel 0 Rx register +const TUint32 KHwI2S0RxPhys = KHwI2S0Phys + KHoI2SRx; + +/** +Constructor for the NE1_TBVariant playback shared chunk sound driver physical device driver (PDD). +*/ +DNE1_TBSoundScPddChannel::DNE1_TBSoundScPddChannel(TSoundDirection aSoundDirection) : + iPowerUpDfc(PowerUpCallback, this, 0) + { + // The data transfer direction for this unit is specified as the constuctor parameter + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::DNE1_TBSoundScPddChannel()", aSoundDirection)); + + iCaps.iDirection = aSoundDirection; + + // store direction for I2s calls + if(aSoundDirection == ESoundDirRecord) + { + iI2sDirection = I2s::ERx; + } + else + { + iI2sDirection = I2s::ETx; + } + } + +/** +Destructor for the NE1_TBVariant playback shared chunk sound driver physical device driver (PDD). +*/ +DNE1_TBSoundScPddChannel::~DNE1_TBSoundScPddChannel() + { + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::~DNE1_TBSoundScPddChannel()", iCaps.iDirection)); + + // Delete the DMA request objects + for (TInt i=0; iClose(); + } + } + +/** +Second stage constructor for the NE1_TBVariant playback shared chunk sound driver physical device driver (PDD). +Note that this constructor is called before the second stage constructor for the LDD so it is not +possible to call methods on the LDD here. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DNE1_TBSoundScPddChannel::DoCreate() + { + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::DoCreate", iCaps.iDirection)); + TInt r = KErrNone; + + // Setup the capabilities of this device. + SetCaps(); + + if (iCaps.iDirection == ESoundDirRecord) + { + iPowerUpDfc.SetDfcQ(DfcQ(KSoundScRxUnit0)); + } + else + { + iPowerUpDfc.SetDfcQ(DfcQ(KSoundScTxUnit0)); + } + + // Setup the DMA channel information for this channel. + // note, that the channel type (Playback/Record) is stored in the iDirection + // and the I2s::TI2sDirection in iI2sDirection. + TDmaChannel::SCreateInfo info; + if (iCaps.iDirection == ESoundDirRecord) + { + info.iCookie = EDMAChannelI2S0RX; + } + else + { + info.iCookie = EDMAChannelI2S0TX; + } + + if (iCaps.iDirection == ESoundDirRecord) + { + info.iDfcQ = DfcQ(KSoundScRxUnit0); + } + else + { + info.iDfcQ = DfcQ(KSoundScTxUnit0); + } + + info.iDfcPriority = 0; // and set priority to 0 (the same as for RX channel) + info.iDesCount = KMaxDmaRequests; + + // Try to open the DMA channel for a given direction (Playback or Record specified in iCookie) + // If this channel was already opened at this point - the DMA framework will return KErrInUse. + r = TDmaChannel::Open(info, iDmaChannel); + if (r != KErrNone) + { + return r; + } + + // Create the DMA request objects for use with the DMA channel. + for (TInt i = 0; i < KMaxDmaRequests; i++) + { + iDmaRequest[i] = new DNE1_TBSoundScDmaRequest(*iDmaChannel,this, 0); + if (iDmaRequest[i] == NULL) + { + return KErrNoMemory; + } + + r = iDmaRequest[i]->CreateMonoBuffer(); + if (r != KErrNone) + { + return r; + } + } + + // initialize the hardware FIFO of the I2S bus for this particular direction (iI2sDIrection). + // Because on this bus - both channels' (left and right) FIFO can't be enabled separately + // it is enough to call EnableFIFO for either of them (I2s::ELeft in this case). + r = I2s::EnableFIFO(KI2sChanNum, I2s::ELeft, iI2sDirection); + if (r != KErrNone) + { + return r; + } + + // set the I2S bus hardware FIFO threshold for each channel of a given direction + r = I2s::SetFIFOThreshold(KI2sChanNum, I2s::ELeft, iI2sDirection, KFifoThreshold); + if (r != KErrNone) + { + return r; + } + + r = I2s::SetFIFOThreshold(KI2sChanNum, I2s::ERight, iI2sDirection, KFifoThreshold); + if (r != KErrNone) + { + return r; + } + + + return KErrNone; + } + +/** +Return the DFC queue to be used by this playback device. +@return The DFC queue to use. +*/ +TDfcQue* DNE1_TBSoundScPddChannel::DfcQ(TInt /*aUnit*/) + { + return(iPhysicalDevice->iDfcQ); + } + +/** +Called from the LDD to return the shared chunk create information to be used by this play device. +@param aChunkCreateInfo A chunk create info. object to be to be filled with the settings + required for this device. +*/ +void DNE1_TBSoundScPddChannel::GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo) + { + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::GetChunkCreateInfo", iCaps.iDirection)); + + // Setup the shared chunk create information in aChunkCreateInfo for this play device. + aChunkCreateInfo.iType = TChunkCreateInfo::ESharedKernelMultiple; + aChunkCreateInfo.iMapAttr = EMapAttrFullyBlocking | EMapAttrWriteUser; // not cached, user writable + aChunkCreateInfo.iOwnsMemory = ETrue; // Using RAM pages. + aChunkCreateInfo.iDestroyedDfc = NULL; // No chunk destroy DFC. + } + +/** +Called from the LDD to return the capabilities of this device. +@param aCapsBuf A packaged TSoundFormatsSupportedV02 object to be filled with the play + capabilities of this device. This descriptor is in kernel memory and can be accessed directly. +@see TSoundFormatsSupportedV02. +*/ +void DNE1_TBSoundScPddChannel::Caps(TDes8& aCapsBuf) const + { + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::Caps", iCaps.iDirection)); + + // Copy iCaps back. + TPtrC8 ptr((const TUint8*)&iCaps,sizeof(iCaps)); + aCapsBuf.FillZ(aCapsBuf.MaxLength()); + aCapsBuf=ptr.Left(Min(ptr.Length(),aCapsBuf.MaxLength())); + } + +/** +Called from the LDD to return the maximum transfer length in bytes that this device can support in a single data transfer. +@return The maximum transfer length in bytes. +*/ +TInt DNE1_TBSoundScPddChannel::MaxTransferLen() const + { + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::MaxTransferLen() %x (%d)", iCaps.iDirection,KMaxDmaTransferLen,KMaxDmaTransferLen)); + return(KMaxDmaTransferLen); + } + +/** +Called from the LDD to configure or reconfigure the device using the the configuration supplied. +@param aConfigBuf A packaged TCurrentSoundFormatV02 object which contains the new configuration settings. + This descriptor is in kernel memory and can be accessed directly. +@return KErrNone if successful, otherwise one of the other system wide error codes. +@see TCurrentSoundFormatV02. +*/ +TInt DNE1_TBSoundScPddChannel::SetConfig(const TDesC8& aConfigBuf) + { + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::SetConfig", iCaps.iDirection)); + TInt r=KErrNone; + + // Read the new configuration from the LDD. + TCurrentSoundFormatV02 config; + TPtr8 ptr((TUint8*)&config,sizeof(config)); + Kern::InfoCopy(ptr,aConfigBuf); + + // Set the I2S interface as bidirectional and master + TI2sConfigV01 i2sconfig = {I2s::EMaster, I2s::EBidirectional}; + TPckgBuf i2sconf(i2sconfig); + + r = I2s::ConfigureInterface(KI2sChanNum, &i2sconf); + if(r != KErrNone) + { + return r; + } + + // Apply the specified audio configuration to the audio device. + if(config.iChannels > 2) + { + return KErrNotSupported; + } + + r = I2s::EnableDMA(KI2sChanNum, iI2sDirection); + if(r != KErrNone) + { + return r; + } + + switch (config.iEncoding) + { + case ESoundEncoding16BitPCM: + r = I2s::SetSampleLength(KI2sChanNum, I2s::ELeft, I2s::ESample16Bit); + if(r!=KErrNone) + { + break; + } + r = I2s::SetFrameLengthAndFormat(KI2sChanNum, I2s::EFrame48Bit, 16); + break; + default: + r = KErrNotSupported; + } + + // might be also be'KErrInUse' here - so we shouldn't continue.. + if(r!=KErrNone) + { + return r; + } + + // BPS = rate * bytes_per_sample * num_of_channels + switch(config.iRate) + { + case ESoundRate11025Hz: + r = I2s::SetSamplingRate(KI2sChanNum, I2s::E11_025KHz); + break; + + case ESoundRate22050Hz: + r = I2s::SetSamplingRate(KI2sChanNum, I2s::E22_05KHz); + break; + + case ESoundRate44100Hz: + r = I2s::SetSamplingRate(KI2sChanNum, I2s::E44_1KHz); + break; + + default: + r = KErrNotSupported; + } + + // if we support it - copy the new configuration + if(r == KErrNone) + { + iCurrentConfig = config; + } + return(r); + } + +/** +Called from the LDD to set the play volume. +@param aVolume The play volume to be set - a value in the range 0 to 255. The value 255 equates + to the maximum volume and each value below this equates to a 0.5dB step below it. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DNE1_TBSoundScPddChannel::SetVolume(TInt aVolume) + { + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::SetVolume", iCaps.iDirection)); + TInt r; + // Set the specified play volume on the audio device. + if (iCaps.iDirection == ESoundDirRecord) + { + r = iPhysicalDevice->iCodec->SetRecordVolume(aVolume); + } + else + { + r = iPhysicalDevice->iCodec->SetPlayVolume(aVolume); + } + return(r); + } + +/** +Called from the LDD to prepare the audio device for playback. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ + +TInt DNE1_TBSoundScPddChannel::StartTransfer() + { + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::StartTransfer", iCaps.iDirection)); + TInt r = I2s::Start(KI2sChanNum, iI2sDirection); + return(r); + } + +/** +Called from the LDD to initiate the playback of a portion of data to the audio device. +When the transfer is complete, the PDD signals this event using the LDD function PlayCallback(). +@param aTransferID A value assigned by the LDD to allow it to uniquely identify a particular transfer fragment. +@param aLinAddr The linear address within the shared chunk of the start of the data to be played. +@param aPhysAddr The physical address within the shared chunk of the start of the data to be played. +@param aNumBytes The number of bytes to be played. +@return KErrNone if the transfer has been initiated successfully; + KErrNotReady if the device is unable to accept the transfer for the moment; + otherwise one of the other system-wide error codes. +*/ +TInt DNE1_TBSoundScPddChannel::TransferData(TUint aTransferID,TLinAddr aLinAddr,TPhysAddr /*aPhysAddr*/,TInt aNumBytes) + { + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::TransferData(ID:%xH,Addr:%xH,Len:%d)",iCaps.iDirection,aTransferID,aLinAddr,aNumBytes)); + TInt r = KErrNone; + + // Check that we can accept the request + if (iPendingPlay >= KMaxDmaRequests) + { + return KErrNotReady; + } + else + { + // Set the DMA transfer.. + // DSoundScDmaRequest, as a friend class checks iChannels and iDirection of the transfer + r = iDmaRequest[iFlag]->SetDmaTransfer(aTransferID, aLinAddr, aNumBytes); + if (r != KErrNone) + { + __KTRACE_SND(Kern::Printf("DMA Fragment error (%d), r= %d", iCaps.iDirection, r)); + return r; + } + else + { + iDmaRequest[iFlag]->Queue(); + iPendingPlay++; + if ((++iFlag) >= KMaxDmaRequests) + iFlag = 0; + } + } + return KErrNone; + } + +/** +Called from the LDD to terminate the playback of a data to the device and to release any resources necessary for playback. +This is called soon after the last pending play request from the client has been completed. Once this function had been +called, the LDD will not issue any further TransferData() commands without first issueing a StartTransfer() command. +*/ +void DNE1_TBSoundScPddChannel::StopTransfer() + { + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::StopTransfer", iCaps.iDirection)); + + // Stop the DMA channel. +#ifdef _DEBUG + TInt r = I2s::Stop(KI2sChanNum, iI2sDirection); + __ASSERT_DEBUG(r == KErrNone, Kern::Fault(KSoundPDDPanicCat, __LINE__)); +#else + I2s::Stop(KI2sChanNum, iI2sDirection); +#endif + + iDmaChannel->CancelAll(); + iFlag = 0; + iPendingPlay = 0; + } + +/** +Called from the LDD to halt the playback of data to the sound device but not to release any resources necessary for +playback. +If possible, any active transfer should be suspended in such a way that it can be resumed later - starting from next +sample following the one last played. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DNE1_TBSoundScPddChannel::PauseTransfer() + { + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::PauseTransfer, pending %d", iCaps.iDirection, iPendingPlay)); + + // Halt transfer on the audio device. + TInt r = I2s::Stop(KI2sChanNum, iI2sDirection); + if(r != KErrNone) + { + return r; + } + + if (iCaps.iDirection == ESoundDirRecord) + { + // for Record, we need to figure out how much data was actually + // transfered and provide this to the LDD.. + if (iPendingPlay) + { + iDmaChannel->CancelAll(); + TInt byteCount = 0; // Unless dma API is extended.. + Ldd()->RecordCallback(0,KErrNone, byteCount); // We can use a NULL transfer ID when pausing. + iPendingPlay=0; + } + iFlag=0; + } + + return(r); + } + +/** +Called from the LDD to resume the playback of data to the sound device following a request to halt playback. +If possible, any transfer which was active when the device was halted should be resumed - starting from next sample +following the one last played. Once complete, it should be reported using PlayCallback() +as normal. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DNE1_TBSoundScPddChannel::ResumeTransfer() + { + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::ResumeTransfer, pending %d", iCaps.iDirection, iPendingPlay)); + + // Resume playback on the audio device. + TInt r = I2s::Start(KI2sChanNum, iI2sDirection); + return(r); + } + + +NFastSemaphore DNE1_TBSoundScPddChannel::iFastSem; + +void DNE1_TBSoundScPddChannel::PowerUpCallback (TAny *aArg) + { + DNE1_TBSoundScPddChannel *a= (DNE1_TBSoundScPddChannel*)aArg; + __KTRACE_SND(Kern::Printf("powerUpCallback(%d)", a->iCaps.iDirection)); + + // PowerUp the Codec + a->iPowerUpStatus = RCS42AudioCodec::Open(a->iPhysicalDevice->iCodec); + + // signal will unblock the thread blocked in call to PowerUp() method. + NKern::FSSignal(&a->iFastSem); + } + +/** +Called from the LDD to power up the sound device when the channel +is first opened and if ever the phone is brought out of standby mode. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DNE1_TBSoundScPddChannel::PowerUp() + { + // Power up the audio device. + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::PowerUp", iCaps.iDirection)); + + // need to power up the device in the context of the driver's thread + // (blocking the calling thread) + TDfcQue* dfcQ; + if (iCaps.iDirection == ESoundDirRecord) + { + dfcQ = DfcQ(KSoundScRxUnit0); + } + else + { + dfcQ = DfcQ(KSoundScTxUnit0); + } + + if(dfcQ->iThread != NKern::CurrentThread()) + { + iPowerUpDfc.Enque(); + iFastSem.iOwningThread = NKern::CurrentThread(); + NKern::FSWait(&iFastSem); + } + else + { + iPowerUpStatus = RCS42AudioCodec::Open(iPhysicalDevice->iCodec); + } + + return iPowerUpStatus; + } + +/** +Called from the LDD in the context of the driver thread to power down the sound device when the +channel is closed and just before the phone powers down when being turned off or going into standby. +*/ +void DNE1_TBSoundScPddChannel::PowerDown() + { + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::PowerDown", iCaps.iDirection)); + // Power down the audio device. + // note, that reference-counting Codec will be powered-down if this call closes the last instance + RCS42AudioCodec::Close(iPhysicalDevice->iCodec); + } + +/** +Called from the LDD to handle a custom configuration request. +@param aFunction A number identifying the request. +@param aParam A 32-bit value passed to the driver. Its meaning depends on the request. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DNE1_TBSoundScPddChannel::CustomConfig(TInt /*aFunction*/,TAny* /*aParam*/) + { + return(KErrNotSupported); + } + +/** +Called each time a playback DMA transfer completes - from the DMA callback function in the sound thread's DFC context. +@param aTransferID The transfer ID of the DMA transfer. +@param aTransferResult The result of the DMA transfer. +@param aBytesTransferred The number of bytes transferred. +*/ +void DNE1_TBSoundScPddChannel::PlayCallback(TUint aTransferID,TInt aTransferResult,TInt aBytesTransferred) + { + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::PlayCallback, ID %x, result %d, pending: %d", iCaps.iDirection, aTransferID, aTransferResult, iPendingPlay)); + + --iPendingPlay; + + if(iCaps.iDirection == ESoundDirRecord) + { + Ldd()->RecordCallback(aTransferID,aTransferResult,aBytesTransferred); + } + else + { + Ldd()->PlayCallback(aTransferID,aTransferResult,aBytesTransferred); + } + } + +/** +Initialise the data member DNE1_TBSoundScPddChannel::iCaps with the play capabilities of this audio playback device. +*/ +void DNE1_TBSoundScPddChannel::SetCaps() + { + __KTRACE_SND(Kern::Printf("DNE1_TBSoundScPddChannel(%d)::SetCaps", iCaps.iDirection)); + + // The audio channel configurations supported by this unit + // This unit supports both mono and stereo + iCaps.iChannels = (KSoundMonoChannel | KSoundStereoChannel); + + // This unit supports only some of the sample rates offered by Symbian OS + iCaps.iRates = (KSoundRate11025Hz | KSoundRate22050Hz | KSoundRate44100Hz); + + // The encoding formats supported + // until we'll be able to set the transfer source/dest lengths for DMA transfers + // only support for this one + iCaps.iEncodings = KSoundEncoding16BitPCM; + + // This unit only supports interleaved data format when playing stereo; that is, a PCM data + // stream where the left and right channel samples are interleaved as L-R-L-R-L-R etc. + iCaps.iDataFormats = KSoundDataFormatInterleaved; + + // The minimum request size that the device can support. All requests to play or record data must be of a + // length that is a multiple of this value. + iCaps.iRequestMinSize = 4; + + // The logarithm to base 2 of the alignment required for request arguments. All requests to play or + // record data must specify locations in the shared chunk which conform to this alignment. + iCaps.iRequestAlignment = 2; + + // Indicates whether this unit is capable of detecting changes in its hardware configuration. + iCaps.iHwConfigNotificationSupport = EFalse; + } + +/** +Constructor for a shared chunk sound driver playback DMA request. +*/ +DNE1_TBSoundScDmaRequest::DNE1_TBSoundScDmaRequest(TDmaChannel& aChannel, DNE1_TBSoundScPddChannel* aPdd, TInt aMaxTransferSize) + : DDmaRequest(aChannel,DNE1_TBSoundScDmaRequest::DmaService,this,aMaxTransferSize), + iPdd(aPdd) + { + } + +DNE1_TBSoundScDmaRequest::~DNE1_TBSoundScDmaRequest() + { + // release buffer used for mono playback + if (iChunk) + { + iChunk->Close(NULL); + } + + if (iBuffPhys) + { + Epoc::FreePhysicalRam(iBuffPhys, KMaxDmaTransferLen*2); + } + } + +TInt DNE1_TBSoundScDmaRequest::CreateMonoBuffer() + { + // alloc memory for buffer - we might need to play mono samples.. + TInt r = Epoc::AllocPhysicalRam(KMaxDmaTransferLen*2, iBuffPhys); + if(r != KErrNone) + { + return r; + } + + // map this buffer as non-cachable and writtable only by supervisor. + r = DPlatChunkHw::New(iChunk, iBuffPhys, KMaxDmaTransferLen*2, + EMapAttrSupRw | EMapAttrFullyBlocking); + if (r != KErrNone) + { + return r; + } + + iBufLin = iChunk->LinearAddress(); + + return KErrNone; + } + +// +TInt DNE1_TBSoundScDmaRequest::SetDmaTransfer(TUint aTransferID, TLinAddr aLinAddr, TInt aNumBytes) + { + __ASSERT_DEBUG(iBufLin != NULL, Kern::Fault(KSoundPDDPanicCat, __LINE__)); + TInt r = KErrNone; + + // store TransferID + iTransferID = aTransferID; + + if (iPdd->iCurrentConfig.iChannels == 1) + { + // Set the DMA source information - local buffer, which is always + // twice as big for mono transfers.. + iTransferSize = aNumBytes*2; + + // Store the original address of the data supplied.. this will be used + // as the destination address for recorded mono data.. + if (iPdd->iCaps.iDirection == ESoundDirRecord) + { + // store address of the orginal buffer, + // where we need to copy the recorded data back - after the transfer has finished + iAddrLinOrig = aLinAddr; + + r = Fragment(KHwI2S0RxPhys, iBufLin, iTransferSize, + KDmaMemDest | KDmaIncDest | KDmaPhysAddrSrc, + (TUint32)this); + } + else // this is a Play (Tx) unit + // This is a mono transfer request so we need to copy data to the internal buffer + // and transfer it as interleaved stereo - since this is the only format supported + // by the I2S bus. + { + TInt16 *src = (TInt16*)aLinAddr; + TInt32 *dst = (TInt32*)iBufLin; + + // copy data to the local buffer (2 bytes at the time) -to play mono in both channels + for (TInt i = 0; i < aNumBytes/2; i++) + { + *dst++ = TInt32((*src) << 16) | (*src & 0xffff); + src++; + } + + r = Fragment(iBufLin, KHwI2S0TxPhys, iTransferSize, + KDmaMemSrc | KDmaIncSrc | KDmaPhysAddrDest, + (TUint32)this); + } + } + else // it's stereo, interleaved data, which can be transferred directly + { + // Supply the DMA source information - original data in the shared chunk + iTransferSize = aNumBytes; + + if (iPdd->iCaps.iDirection == ESoundDirRecord) + { + r = Fragment(KHwI2S0RxPhys, aLinAddr, iTransferSize, + KDmaMemDest | KDmaIncDest | KDmaPhysAddrSrc, + (TUint32)this); + } + else // this is a Play (Tx) unit + { + r = Fragment(aLinAddr, KHwI2S0TxPhys, iTransferSize, + KDmaMemSrc | KDmaIncSrc | KDmaPhysAddrDest, + (TUint32)this); + } + } + return r; + } + +/** +DMA tx service routine. Called in the sound thread's DFC context by the s/w DMA controller. +@param aResult Status of DMA transfer. +@param aArg Argument passed to DMA controller. +*/ +void DNE1_TBSoundScDmaRequest::DmaService(TResult aResult, TAny* aArg) + { + DNE1_TBSoundScDmaRequest& req = *(DNE1_TBSoundScDmaRequest*)aArg; + __KTRACE_SND( Kern::Printf("DmaService(%d) %d",req.iPdd->iCaps.iDirection, aResult)); + + TInt res = KErrNone; + TInt bytesTransferred = req.iTransferSize; + if (aResult!=DDmaRequest::EOk) + { + res = KErrCorrupt; + bytesTransferred = 0; + } + + // if this was mono transfered as stereo.. + if (req.iPdd->iCurrentConfig.iChannels == 1) + { + // adjust back the number of bytes transfered + bytesTransferred /= 2; + + // if this request is a part of record unit + // copy data to back to the shared chunk provided by the LDD + if (req.iPdd->iCaps.iDirection == ESoundDirRecord) + { + TInt32 *src = (TInt32*)req.iBufLin; + TInt16 *dst = (TInt16*)req.iAddrLinOrig; + + for (TInt i = 0; i < bytesTransferred; i+=2) + { + *dst++ = TInt16(*src++); + } + } + } + + // Inform the LDD of the result of the transfer. + req.iPdd->PlayCallback(req.iTransferID,res,bytesTransferred); + + return; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/soundsc_v2.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/soundsc_v2.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/soundscne1_tb.mmp +* soundsc.pdd NE1_TBVariant shared chunk sound PDD +* +*/ + + + +/** + @file +*/ +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(soundsc_v2,pdd) +targettype pdd +romtarget soundsc.pdd + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) +SYMBIAN_NE1_TB_SYSTEMINCLUDE(specific) +USERINCLUDE ../../../../os/kernelhwsrv/kernel/eka/drivers/iic +USERINCLUDE inc + +#ifdef SMP +SYMBIAN_BASE_SYSTEMINCLUDE(nkernsmp) +#else +SYMBIAN_BASE_SYSTEMINCLUDE(nkern) +#endif + + +//the sound driver +sourcepath soundsc +source soundsc.cpp +source soundsc_channel.cpp + +//the codec +sourcepath specific +source cs42l51.cpp + +library dma2.lib +library VariantTarget(i2s,lib) +library VariantTarget(ecust,lib) +library VariantTarget(gpio,lib) +library iic.lib +uid 0x100039d0 0x1000015c +VENDORID 0x70000001 + +capability all +EPOCALLOWDLLDATA + +MACRO CPU_AFFINITY_ANY + +SMPSAFE + +MACRO DMA_APIV2 diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/specific/cs42l51.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/specific/cs42l51.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,375 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\specific\cs42l51.cpp +* +*/ + + + +#include +#include +#include +#include +#include "cs42l51.h" + +#define __THREAD_AND_CPU Kern::Printf("(Thread %T, CPU: %d)\n", NKern::CurrentThread(), NKern::CurrentCpu()) +//#define __KTRACE_SCODEC(s) s +#define __KTRACE_SCODEC(s) __KTRACE_OPT(KSOUND1, s) + + +#if _DEBUG +static const char KCodecPanicCat[] = "AUDIO CODEC, line:"; +#endif + +// other constants +const TUint KCodecCSIChannel = 0; +const TInt8 KBufGranularity = 8; // width of a transfer word in bits + +// CSI configuration parameters for the data transmission to the Codec. +const TConfigSpiV01 KCodecSpiV01Config = + { + ESpiWordWidth_8, //iWordWidth + 260000, //iClkSpeed + ESpiPolarityHighFallingEdge, //iClkMode + 40, // iTimeoutPeriod + EBigEndian, // iEndianness + EMsbFirst, // iBitOrder + 0, // iTransactionWaitCycles + ESpiCSPinActiveLow //iCsPinActiveMode + }; + +// static members +RCS42AudioCodec* RCS42AudioCodec::iSelf = 0; +TInt RCS42AudioCodec::iRefCnt = 0; + +// default constructor +RCS42AudioCodec::RCS42AudioCodec() : + iHeaderBuff(KCodecSpiV01Config) + { + } + +TInt RCS42AudioCodec::Create() + { + __KTRACE_SCODEC(Kern::Printf("\n\nRCS42AudioCodec::Create()")); + if (!iSelf) + { + iSelf = new RCS42AudioCodec; + if(!iSelf) + { + return KErrNoMemory; + } + } + return KErrNone; + } + +// free resources when the driver is beeing closed. +void RCS42AudioCodec::Destroy() + { + __KTRACE_SCODEC(Kern::Printf("RCS42AudioCodec::Destroy()")); + __ASSERT_DEBUG(iSelf, Kern::Fault(KCodecPanicCat, __LINE__)); + + delete iSelf; + iSelf = 0; // static member + } + +// this static method is called from DNE1_TBSoundScPddChannel::PowerUp() +// to open an instance to the codec. If this is the first instance +// beeing opened - the codec is initialized. +TInt RCS42AudioCodec::Open(RCS42AudioCodec* &aSelf) + { + __KTRACE_SCODEC(Kern::Printf("RCS42AudioCodec::Open()")); + + TInt r = KErrNone; + if(!iSelf) + { + r = Create(); + if(r != KErrNone) + { + return r; + } + } + + if (iRefCnt == 0) + { + r = iSelf->Init(); + if (r != KErrNone) + { + iSelf->PowerDown(); + return r; + } + } + // increment the reference counter + ++iRefCnt; + + // copy object address back to the client + aSelf = iSelf; + + return KErrNone; + } + +// this static method is called from DNE1_TBSoundScPddChannel::PowerDown() +// to close the reference and power down the codec if the last reference is beeing closed. +void RCS42AudioCodec::Close(RCS42AudioCodec* &aSelf) + { + __KTRACE_SCODEC(Kern::Printf("RCS42AudioCodec::Close()")) ; + + if (!aSelf || aSelf != iSelf) + { + return; + } + + // decrement the reference counter + --iRefCnt; + + // if closing the last instance - power down the codec + if (iRefCnt == 0) + { + iSelf->PowerDown(); + aSelf = 0; + Destroy(); + } + } + +// this method powers down the codec +void RCS42AudioCodec::PowerDown() + { + if (iSelf) + { + iSelf->StartWrite(); + iSelf->Write(KHwCS42L51DACOutputControl, + KHtCS42L51DACOutputControl_DACAB_MUTE); + + // - set PDN bit + iSelf->Write(KHwCS42L51PwrCtrl, KHtCS42L51PwrCtrl_PDN); + +#ifdef _DEBUG + TInt r = iSelf->StopWrite(); + __ASSERT_DEBUG(r == KErrNone, Kern::Printf("Coulnd't power down the CODEC r=%d ", r)); + __ASSERT_DEBUG(r == KErrNone, Kern::Fault(KCodecPanicCat, __LINE__)); +#else + iSelf->StopWrite(); +#endif + + // put !reset back to low.. + GPIO::SetOutputState(KCodecResetPin, GPIO::ELow); + } + } + + +// this is an internal method - to synchronously write the data to the bus. It sets up the transfer +// and waits for Interrupt - which puts back the CS (Chip Select) pin - to low after the +// data was sent out of the bus. +TInt RCS42AudioCodec::DoWrite(TUint16 aRegAddr, TUint16 aData) + { + __KTRACE_SCODEC(Kern::Printf("RCS42AudioCodec::DoWrite()")); + TInt r = KErrNone; + + iTransBuff().iRegister = aRegAddr; + iTransBuff().iData = aData; + + // create a transfer object.. + TIicBusTransfer transfer(TIicBusTransfer::EMasterWrite, KBufGranularity, &iTransBuff); + + // Create transaction + TIicBusTransaction transaction(&iHeaderBuff, &transfer); + + // synchronously queue the write transaction + r = IicBus::QueueTransaction(iCsiBusConfig, &transaction); + return r; + } + +// to avoid multiple checking for each Write() call - if they are called in a row, +// precede each block of writes to be checked with StartWrite() which clears the iResult. +void RCS42AudioCodec::StartWrite() + { +#if _DEBUG + iStartWriteCalled = ETrue; +#endif + iResult = KErrNone; + } + +// After each block calls to Write() check the global status of them by calling this method. +TInt RCS42AudioCodec::StopWrite() + { +#if _DEBUG + iStartWriteCalled = EFalse; +#endif + return iResult; + } + +// this is an internal method - used to configure the codec. It can be called +// multiple times - whithout checkin for results. Precondition is - to call StartWrite() +// and the overall result of multiple calls to this method are gathered using StopWrite() +void RCS42AudioCodec::Write(TUint16 aRegAddr, TUint16 aData) + { + __ASSERT_DEBUG(iStartWriteCalled, Kern::Printf("block of multiple Write() calls should be preceded with StartWrite()")); + __ASSERT_DEBUG(iStartWriteCalled, Kern::Fault(KCodecPanicCat, __LINE__)); + + if (iResult != KErrNone) + { + return; // there was an error during one of previous write calls, just return + } + // if all calls proceeding StartWrite() were successful, continue to call the proper write + iResult = DoWrite(aRegAddr, aData); + } + +// This method is used to configure the CSI interface and then - the Codec. +TInt RCS42AudioCodec::Init() + { + __KTRACE_SCODEC(Kern::Printf("RCS42AudioCodec::Init()")); + TUint32 val; + + // First byte for the Cocec's write request on the CSI bus: (first seven bits-address, 8th-Write idication) + iTransBuff().iAddress = KCodecWriteCommand; + + // Enter the BusRealisation config specific to CSI + SET_BUS_TYPE(iCsiBusConfig,DIicBusChannel::ESpi); //Bus Type + SET_CHAN_NUM(iCsiBusConfig,(TUint8)KCodecCSIChannel); // SPI uses channel numbers 1,2 (CSI0 and CSI1) + SET_SLAVE_ADDR(iCsiBusConfig,KCodecCSPin); // Codec Pin Number + + // enable and configure pin 25 - it is connected to the chip's reset line + GPIO::SetPinMode(KCodecResetPin, GPIO::EEnabled); + GPIO::SetPinDirection(KCodecResetPin, GPIO::EOutput); + GPIO::SetDebounceTime(KCodecResetPin, 0); + + //==================================== + //configure the CODEC: + // put !reset line high to start the power-up sequence.. + GPIO::SetOutputState(KCodecResetPin, GPIO::EHigh); + + // start multiple Write() block here + StartWrite(); + + // Write are used here.. + // power-up sequence.. + Write(KHwCS42L51PwrCtrl, KHtCS42L51PwrCtrl_PDN); + Write(KHwCS42L51PwrCtrl, KHtCS42L51PwrCtrl_PDN_ALL); + + // freeze all registers.. until are set-up.. + Write(KHwCS42L51DACControl, KHtCS42L51DACControl_FREEZE); + + // Mic power control and speed control (0x03) + Write(KHwCS42L51MicPwrSpeed, KHtCS42L51MicPwrSpeed_AUTO + | KHtCS42L51MicPwrSpeed_MCLKDIV2); // auto, + + // interface control (0x04) // serial port settings.. + // I2s, Slave, SDOUT->SDIN internally connected.. Digimix->ON? + + // use I2S format, Slave + iInterfaceCtrlVal = KHCS42L51CtrlI2sUpto24bit << KHsCS42L51CtrlFormat; + + // Digital & Mic mix + iInterfaceCtrlVal |= KHtCS42L51Ctrl_DIGMIX | KHtCS42L51Ctrl_MICMIX; + Write(KHwCS42L51Ctrl, iInterfaceCtrlVal); + + // MIC Control - enable mic pre-amplifierboost (there is also ADC digital boost) + // which we can use in addition to this one - but it would- work fine whitout any. + val = KHtCS42L51MicCtrl_MICA_BOOST; + Write(KHwCS42L51MicCtrl, val); + + // ADCx Input Select, Invert & Mute + /* + PDN_PGAx AINx_MUX[1:0] Selected Path to ADC + 0 00 AIN1x-->PGAx + 0 01 AIN2x-->PGAx + 0 10 AIN3x/MICINx-->PGAx + 0 11 AIN3x/MICINx-->Pre-Amp(+16/+32 dB Gain)-->PGAx + 1 00 AIN1x + 1 01 AIN2x + 1 10 AIN3x/MICINx + 1 11 Reserved */ + + val = 3 << KHsCS42L51ADCInputMute_AINA_MUX; + val |= 3 << KHsCS42L51ADCInputMute_AINB_MUX; + Write(KHwCS42L51ADCInputMute, val); + + // DAC output select (0x08) + // HP_GAIN2 HP_GAIN1 HP_GAIN0 DAC_SNGVOL INV_PCMB INV_PCMA DACB_MUTE DACA_MUTE + Write(KHwCS42L51DACOutputControl, KHtCS42L51DACOutputControl_DAC_SNGVOL); + + // ALCX & PGAX ctrl, A(0x0A), B (0x0B) + Write(KHwCS42L51ALC_PGA_A_Control, 0); + Write(KHwCS42L51ALC_PGA_B_Control, 0); + + // ADCx Mixer Volume Ctrl A(0x0E), B (0x0F) + Write(KHwCS42L51ALC_ADC_A_MixVolume, KHbCS42L51ALC_Volume_Min); + Write(KHwCS42L51ALC_ADC_B_MixVolume, KHbCS42L51ALC_Volume_Min); + + // PCMx Volume Ctrl A(0x10), B (0x11) + Write(KHwCS42L51ALC_PCM_A_MixVolume, 0x18); + Write(KHwCS42L51ALC_PCM_B_MixVolume, 0x18); + + // Volume Control: AOUTA (Address 16h) & AOUTB (Address 17h) + Write(KHwCS42L51ALC_Out_A_Volume, KHbCS42L51ALC_Volume_Min); + Write(KHwCS42L51ALC_Out_B_Volume, KHbCS42L51ALC_Volume_Min); + + // DAC Control (Address 09h) + // 7 6 5 4 3 2 1 0 + // DATA_SEL1 DATA_SEL0 FREEZE Reserved DEEMPH AMUTE DAC_SZC1 DAC_SZC0 + // DATA_SEL1 DATA_SEL0: + // 00 - PCM Serial Port to DAC + // 01 - Signal Processing Engine to DAC + // 10 - ADC Serial Port to DAC (11 - Reserved) + Write(KHwCS42L51DACControl, 1< +#include "platform.h" +#include +#include + + + +// The TKeyboardState class is used to encapsulate the state of +// the keyboard. i.e which keys are currently being pressed. +// To determine which keys are being pressed, typically a voltage +// is applied to each row in turn (or column, depending on the hardware) +// and the output is read resulting in a bitmask for each row. +// +// For example, the keys could be arranged as follows (where a '1' indicates +// that a key is currently being pressed : +// EXAMPLE ONLY +// +// Translated +// Column# 0 1 2 3 4 5 6 7 8 9 A B C D E F KeyCode +// Row# +// 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 60 to 6F +// 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50 to 5F +// 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 40 to 4F +// 3 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 30 to 3F +// Input-> 2 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 20 to 2F +// 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 to 1F +// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 to 0F +// +// output-> 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 +// +// TO DO: (mandadory) +// Modify TKeyboardState (or provide an alternative) to model the +// real keyboard state +// +// EXAMPLE ONLY +class TKeyboardState + { +public: + + enum TDimensions + { + KRows = 7, + KColumns = 16 + }; + +public: + TKeyboardState(); + void Clear(); + TBool IsKeyReady(); + TUint32 GetKeyCode(); + TKeyboardState operator&(const TKeyboardState& aState); + TKeyboardState operator|(const TKeyboardState& aState); + TKeyboardState operator~(); + +public: + TUint32 iKeyBitMask[KRows]; + }; + +/** +Constructor +*/ +TKeyboardState::TKeyboardState() + { + Clear(); + } + +/** +Clears the array of bitmasks +*/ +void TKeyboardState::Clear() + { + for (TInt row=0; rowPoll(); + } + + +/** +Reads scan codes from the keyboard until there are none left +Called from the keyboard-polling timer's DFC +*/ +void DKeyboardNE1_TB::Poll() + { + __KTRACE_OPT(KHARDWARE,Kern::Printf("DKeyboardNE1_TB::EventDfc")); + + + TKeyboardState keyState; + + // + // TO DO: (mandatory) + // Read new key state into the array of bitmasks in keyState + // This typically involves applying a voltage to each row from 0 to KRows-1, + // reading the output state of the i/o lines at every step + // - this represents the keys that are pressed on each row - + // and storing the output of each row as a bitmask into keyState.iKeyBitMask[n], + // where n = the row being accessed + // + + // To enable a simple de-bouncing algorithm, + // work out which keys have been pressed down for at least two timer + // ticks by AND-ing together the last bitmask with the current bitmask + TKeyboardState keysStillDown = keyState & iKeyStateLast; + + + // Similarly, work out which keys have been "un-pressed" for at least two timer + // ticks by AND-ing together the one's complement of the last bitmask with the + // one's complement of the current bitmask and + // then AND-ing this with the set of keys for which we have sent an EKeyDown + // event to give the set of keys for which we need to send an EKeyUp event + TKeyboardState keysStillUp = (~keyState & ~iKeyStateLast) & iKeysDown; + + // save the current state for next time + iKeyStateLast = keyState; + + // update the set of keys for which we have sent an EKeyDown event + iKeysDown = iKeysDown | keysStillDown; + iKeysDown = iKeysDown & ~keysStillUp; + + // process all the key-down events + while (keysStillDown.IsKeyReady()) // while there are keys we haven't processed + { + TRawEvent e; + TUint keyCode = keysStillDown.GetKeyCode(); // Read keycodes from bitmask + + __KTRACE_OPT(KHARDWARE,Kern::Printf("EKeyDown: #%02x\n",keyCode)); + + // + // TO DO: (mandatory) + // + // Convert from hardware scancode to EPOC scancode and send the scancode as an event (key pressed or released) + // as per below EXAMPLE ONLY: + // + __ASSERT_DEBUG(keyCode < (sizeof(convertCode) / sizeof(TUint8)), Kern::Fault("Keyboard", __LINE__)); + TUint8 stdKey = convertCode[keyCode]; + + e.Set(TRawEvent::EKeyDown, stdKey, 0); + Kern::AddEvent(e); + } + + // process all the key-up events + while (keysStillUp.IsKeyReady()) // while there are keys we haven't processed + { + TRawEvent e; + TUint keyCode = keysStillUp.GetKeyCode(); // Read keycodes from bitmask + + __KTRACE_OPT(KHARDWARE,Kern::Printf("EKeyUp: #%02x\n",keyCode)); + + // + // TO DO: (mandatory) + // + // Convert from hardware scancode to EPOC scancode and send the scancode as an event (key pressed or released) + // as per below EXAMPLE ONLY: + // + __ASSERT_DEBUG(keyCode < (sizeof(convertCode) / sizeof(TUint8)), Kern::Fault("Keyboard", __LINE__)); + TUint8 stdKey = convertCode[keyCode]; + + e.Set(TRawEvent::EKeyUp, stdKey, 0); + Kern::AddEvent(e); + } + + // start the timer again + iTimer.OneShot(iTimerTicks); + } + + + +/** +Notifies the peripheral of system power up. +Called by the power manager during a transition from standby. +Schedules a DFC to handle the power up. +*/ +void DKeyboardNE1_TB::PowerUp() + { + iPowerUpDfc.Enque(); + } + + +/** +static DFC to handle powering up the keyboard + +@param aPtr A pointer to an instance of DKeyboardNE1_TB +*/ +void DKeyboardNE1_TB::PowerUpDfcFn(TAny* aPtr) + { + ((DKeyboardNE1_TB*)aPtr)->PowerUpDfc(); + } + + +/** +DFC to handle powering up the keyboard +*/ +void DKeyboardNE1_TB::PowerUpDfc() + { + __KTRACE_OPT(KPOWER, Kern::Printf("DKeyboardNE1_TB::PowerUpDfc()")); + KeyboardOn(); + + // Indicate to power handle that powered up is complete + PowerUpDone(); + } + +/** +Powers up the keyboard +May be called as a result of a power transition or from the HAL +*/ +void DKeyboardNE1_TB::KeyboardOn() + { + __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardNE1_TB::KeyboardOn() iKeyboardOn=%d", iKeyboardOn)); + + if (!iKeyboardOn) // make sure we don't initialize more than once + KeyboardPowerUp(); + } + +/** +Powers up the keyboard +Assumes that the keyboard is currently powered off +*/ +void DKeyboardNE1_TB::KeyboardPowerUp() + { + __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardNE1_TB::KeyboardPowerUp()")); + + iKeyboardOn = ETrue; + + iKeyStateLast.Clear(); + iKeysDown.Clear(); + + // Send key up events for EStdKeyOff (Fn+Esc) event + TRawEvent e; + e.Set(TRawEvent::EKeyUp,EStdKeyEscape,0); + Kern::AddEvent(e); + e.Set(TRawEvent::EKeyUp,EStdKeyLeftFunc,0); + Kern::AddEvent(e); + + // Start the periodic tick for the selected rate. + // This will call TimerCallback() in the context of an ISR + iTimer.OneShot(iTimerTicks); + } + + +/** +Requests keyboard to power down. +Called by the power manager during a transition to standby or power off +Schedules a DFC to handle the power up. + +@param aPowerState the current power state +*/ +void DKeyboardNE1_TB::PowerDown(TPowerState) + { + iPowerDownDfc.Enque(); + } + +/** +static DFC to handle powering down the keyboard + +@param aPtr A pointer to an instance of DKeyboardNE1_TB +*/ +void DKeyboardNE1_TB::PowerDownDfcFn(TAny* aPtr) + { + ((DKeyboardNE1_TB*)aPtr)->PowerDownDfc(); + } + +/** +DFC to handle powering down the keyboard +*/ +void DKeyboardNE1_TB::PowerDownDfc() + { + __KTRACE_OPT(KPOWER, Kern::Printf("DKeyboardNE1_TB::PowerDownDfc()")); + KeyboardOff(); + PowerDownDone(); + } + +/** +Powers down the keyboard +May be called as a result of a power transition or from the HAL +*/ +void DKeyboardNE1_TB::KeyboardOff() + { + __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardNE1_TB::KeyboardOff() iKeyboardOn=%d", iKeyboardOn)); + + // cancel the keyboard-polling timer + iTimerDfc.Cancel(); + iTimer.Cancel(); + + iKeyboardOn = EFalse; + } + + +/** +static message handler for processing power up/down messages +posted internally from HalFunction() + +@param aPtr A pointer to an instance of DKeyboardNE1_TB +*/ +void DKeyboardNE1_TB::HandleMessage(TAny* aPtr) + { + DKeyboardNE1_TB& h=*(DKeyboardNE1_TB*)aPtr; + TMessageBase* pM=h.iMsgQ.iMessage; + if (pM) + h.HandleMsg(pM); + } + +/** +Message handler for processing power up/down messages +posted internally from HalFunction() + +param aMsg A message indicating whether to power the keyboard on or off +*/ +void DKeyboardNE1_TB::HandleMsg(TMessageBase* aMsg) + { + if (aMsg->iValue) + KeyboardOn(); + else + KeyboardOff(); + aMsg->Complete(KErrNone,ETrue); + } + + +/** +Retrieves information about the keyboard +Called from HalFunction() + +@param aInfo a caller-supplied class which on return contains information about the keyboard +*/ +void DKeyboardNE1_TB::KeyboardInfo(TKeyboardInfoV01& aInfo) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardNE1_TB::KeyboardInfo")); + aInfo.iKeyboardType=KConfigKeyboardType; + aInfo.iDeviceKeys=KConfigKeyboardDeviceKeys; + aInfo.iAppsKeys=KConfigKeyboardAppsKeys; + } + + +/** +HAL handler function + +@param aPtr a pointer to an instance of DLcdPowerHandler +@param aFunction the function number +@param a1 an arbitrary parameter +@param a2 an arbitrary parameter +*/ +TInt DKeyboardNE1_TB::HalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2) + { + DKeyboardNE1_TB* pH=(DKeyboardNE1_TB*)aPtr; + return pH->HalFunction(aFunction,a1,a2); + } + + +/** +a HAL entry handling function for HAL group attribute EHalGroupKeyboard + +@param a1 an arbitrary argument +@param a2 an arbitrary argument +@return KErrNone if successful +*/ +TInt DKeyboardNE1_TB::HalFunction(TInt aFunction, TAny* a1, TAny* a2) + { + TInt r=KErrNone; + + __KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardNE1_TB::HalFunction %d", aFunction)); + + switch(aFunction) + { + case EKeyboardHalKeyboardInfo: + { + TPckgBuf kPckg; + KeyboardInfo(kPckg()); + Kern::InfoCopy(*(TDes8*)a1,kPckg); + break; + } + + case EKeyboardHalSetKeyboardState: + { + if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EKeyboardHalSetKeyboardState"))) + return KErrPermissionDenied; + if ((TBool)a1) + { + TThreadMessage& m=Kern::Message(); + m.iValue = ETrue; + m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered up + } + else + { + TThreadMessage& m=Kern::Message(); + m.iValue = EFalse; + m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered down + } + } + break; + + case EKeyboardHalKeyboardState: + kumemput32(a1, &iKeyboardOn, sizeof(TBool)); + break; + + default: + r=KErrNotSupported; + break; + } + return r; + } + + + +DECLARE_STANDARD_EXTENSION() + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Starting keyboard driver")); + + // create keyboard driver + TInt r=KErrNoMemory; + DKeyboardNE1_TB* pK=new DKeyboardNE1_TB; + if (pK) + r=pK->Create(); + + __KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r)); + return r; + } diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/specific/keyboard_interrupt.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/specific/keyboard_interrupt.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,396 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\specific\keyboard.cpp +* Access to NE1_TBVariant interruptible keyboard +* The code here implements a simple interrupt-driven keyboard driver. +* This is an alternative to the polled driver in keyboard.cpp. +* This example assumes that we have an intelligent keyboard controller +* which: +* scans the keyboard automatically +* generates an interrupt when a key is pressed or released +* You can use this code as a starting point and modify it to suit +* your hardware. +* +*/ + + + +#include +#include +#include "iolines.h" +#include "platform.h" +#include +#include +// +// +// TO DO: (optional) +// +// Modify this conversion table to suit your keyboard layout +// +// This example assumes that the following keyboard layout: +// +// <----Row0-----><-----Row1-------><---Row2-----><-----Row3-------><-------Row4-----------><------Row5------><-----Row6-------><---Row7---> +// LAlt Column0 +// ' \ TAB Z A X Column1 +// LShift Column2 +// LCtrl Column3 +// Fn Column4 +// Esc Del Q CapLk S C 3 Column5 +// 1 W D V 4 Column6 +// 2 T E F B 5 Column7 +// 9 Y R K G N 6 Column8 +// 0 U O L H M 7 Column9 +// - I P ; J , 8 Column10 +// = Enter [ ' / . Prog Column11 +// RShift Column12 +// BkSp DnArrow ] UpArrow LeftArrow Space RightArrow Column13 +// Column14 +// Column15 +// EXAMPLE ONLY +const TUint8 convertCode[] = + { + EStdKeyNull , EStdKeyLeftAlt , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column0 + EStdKeyNull , EStdKeyHash ,EStdKeyBackSlash, EStdKeyTab , 'Z' , 'A' , 'X' ,EStdKeyNull, // Column1 + EStdKeyNull , EStdKeyNull ,EStdKeyLeftShift, EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column2 + EStdKeyNull , EStdKeyLeftCtrl , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column3 + EStdKeyNull , EStdKeyLeftFunc , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column4 + EStdKeyNull , EStdKeyEscape , EStdKeyDelete , 'Q' , EStdKeyCapsLock , 'S' , 'C' , '3' , // Column5 + EStdKeyNull , '1' , EStdKeyNull , 'W' , EStdKeyNull , 'D' , 'V' , '4' , // Column6 + EStdKeyNull , '2' , 'T' , 'E' , EStdKeyNull , 'F' , 'B' , '5' , // Column7 + EStdKeyNull , '9' , 'Y' , 'R' , 'K' , 'G' , 'N' , '6' , // Column8 + EStdKeyNull , '0' , 'U' , 'O' , 'L' , 'H' , 'M' , '7' , // Column9 + EStdKeyNull , EStdKeyMinus , 'I' , 'P' , EStdKeySemiColon , 'J' , EStdKeyComma , '8' , // Column10 + EStdKeyNull , EStdKeyEquals , EStdKeyEnter ,EStdKeySquareBracketLeft,EStdKeySingleQuote,EStdKeyForwardSlash, EStdKeyFullStop ,EStdKeyMenu, // Column11 + EStdKeyNull , EStdKeyNull ,EStdKeyRightShift, EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column12 + EStdKeyNull , EStdKeyBackspace ,EStdKeyDownArrow,EStdKeySquareBracketRight,EStdKeyUpArrow , EStdKeyLeftArrow , EStdKeySpace ,EStdKeyRightArrow, // Column13 + EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull, // Column14 + EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,EStdKeyNull // Column15 + }; + +// EXAMPLE ONLY +const TInt KFlagKeyPressed = 0x80; // As an example, we'll assume the top bit indicates pressed/released + +// EXAMPLE ONLY +const TKeyboard KConfigKeyboardType = EKeyboard_Full; +const TInt KConfigKeyboardDeviceKeys = 0; +const TInt KConfigKeyboardAppsKeys = 0; +// +// +_LIT(KLitKeyboard,"Keyboard"); + +class DKeyboardNE1_TB : public DPowerHandler + { +public: + DKeyboardNE1_TB(); + TInt Create(); +public: // from DPowerHandler + void PowerUp(); + void PowerDown(TPowerState); + TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2); + void KeyboardInfo(TKeyboardInfoV01& aInfo); + void KeyboardOn(); + void KeyboardOff(); + void HandleMsg(TMessageBase* aMsg); +private: + static void Isr(TAny* aPtr); + static void EventDfcFn(TAny* aPtr); + void EventDfc(); + + void PowerUpDfc(); + static void PowerUpDfcFn(TAny* aPtr); + void PowerDownDfc(); + static void PowerDownDfcFn(TAny* aPtr); +private: + void KeyboardPowerUp(); + TUint GetKeyCode(); + TBool IsKeyReady(); +public: + TDfcQue* iDfcQ; + TMessageQue iMsgQ; + TDfc iPowerUpDfc; + TDfc iPowerDownDfc; +private: + TDfc iEventDfc; + TBool iKeyboardOn; + TInt iIrqHandle; + }; + +LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2) + { + DKeyboardNE1_TB* pH=(DKeyboardNE1_TB*)aPtr; + return pH->HalFunction(aFunction,a1,a2); + } + +void rxMsg(TAny* aPtr) + { + DKeyboardNE1_TB& h=*(DKeyboardNE1_TB*)aPtr; + TMessageBase* pM=h.iMsgQ.iMessage; + if (pM) + h.HandleMsg(pM); + } + +// +// Keyboard class +// +DKeyboardNE1_TB::DKeyboardNE1_TB() + : DPowerHandler(KLitKeyboard), + iMsgQ(rxMsg,this,NULL,1), + iPowerUpDfc(PowerUpDfcFn,this,6), + iPowerDownDfc(PowerDownDfcFn,this,7), + iEventDfc(EventDfcFn,this,1), + iIrqHandle(-1) + { + } + +TInt DKeyboardNE1_TB::Create() +// +// Initialisation. Bind and enable the interrupt. +// + { + iDfcQ=Kern::DfcQue0(); + + iKeyboardOn = EFalse; + // install the HAL function + TInt r=Kern::AddHalEntry(EHalGroupKeyboard,halFunction,this); + if (r!=KErrNone) + return r; + + iEventDfc.SetDfcQ(iDfcQ); + iPowerUpDfc.SetDfcQ(iDfcQ); + iPowerDownDfc.SetDfcQ(iDfcQ); + iMsgQ.SetDfcQ(iDfcQ); + iMsgQ.Receive(); + + // Bind the key event interrupt + r=Interrupt::Bind(KIntIdKeyboard,Isr,this); + if (r>=0) + { + // install the power handler + iIrqHandle = r; + Add(); + KeyboardPowerUp(); + } + return KErrNone; + } + +void DKeyboardNE1_TB::Isr(TAny* aPtr) + { + DKeyboardNE1_TB& k=*(DKeyboardNE1_TB*)aPtr; + Interrupt::Disable(k.iIrqHandle); + k.iEventDfc.Add(); + } + +void DKeyboardNE1_TB::EventDfcFn(TAny* aPtr) + { + ((DKeyboardNE1_TB*)aPtr)->EventDfc(); + } + +void DKeyboardNE1_TB::EventDfc() + { + __KTRACE_OPT(KHARDWARE,Kern::Printf("DKeyboardNE1_TB::EventDfc")); + + TInt irq=NKern::DisableAllInterrupts(); + while (IsKeyReady()) // while there are keys in the controller's output buffer + { + NKern::RestoreInterrupts(irq); + TRawEvent e; + TUint keyCode=GetKeyCode(); // Read keycodes from controller + __KTRACE_OPT(KHARDWARE,Kern::Printf("#%02x",keyCode)); + + // + // TO DO: (mandatory) + // + // Convert from hardware scancode to EPOC scancode and send the scancode as an event (key pressed or released) + // as per below EXAMPLE ONLY: + // + TUint bareCode=keyCode&~KFlagKeyPressed; + TUint8 stdKey=convertCode[bareCode]; + if (keyCode&KFlagKeyPressed) + e.Set(TRawEvent::EKeyUp,stdKey,0); + else + e.Set(TRawEvent::EKeyDown,stdKey,0); + Kern::AddEvent(e); + NKern::Sleep(1); // pause before reading more keycodes + irq=NKern::DisableAllInterrupts(); + } + Interrupt::Enable(iIrqHandle); + NKern::RestoreInterrupts(irq); + } + +TBool DKeyboardNE1_TB::IsKeyReady() + { + // + // TO DO: (mandatory) + // + // Return ETrue if the keyboard controller has a key event waiting to be read + // + + return EFalse; // EXAMPLE ONLY + } + +TUint DKeyboardNE1_TB::GetKeyCode() + { + // + // TO DO: (mandatory) + // + // Read and return the next available keycode from the keyboard controller + // + + return 0; // EXAMPLE ONLY + } + +void DKeyboardNE1_TB::PowerUpDfcFn(TAny* aPtr) + { + ((DKeyboardNE1_TB*)aPtr)->PowerUpDfc(); + } + +void DKeyboardNE1_TB::PowerDownDfcFn(TAny* aPtr) + { + ((DKeyboardNE1_TB*)aPtr)->PowerDownDfc(); + } + + +void DKeyboardNE1_TB::KeyboardPowerUp() + { + __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardNE1_TB::KeyboardPowerUp()")); + + iKeyboardOn = ETrue; + + // Send key up events for EStdKeyOff (Fn+Esc) event + TRawEvent e; + e.Set(TRawEvent::EKeyUp,EStdKeyEscape,0); + Kern::AddEvent(e); + e.Set(TRawEvent::EKeyUp,EStdKeyLeftFunc,0); + Kern::AddEvent(e); + } + +void DKeyboardNE1_TB::PowerUp() + { + iPowerUpDfc.Enque(); // schedules DFC to execute on this driver's thread + } + +void DKeyboardNE1_TB::PowerUpDfc() + { + __KTRACE_OPT(KPOWER, Kern::Printf("DKeyboardNE1_TB::PowerUpDfc()")); + KeyboardOn(); + PowerUpDone(); // must be called from a different thread than PowerUp() + } + +void DKeyboardNE1_TB::KeyboardOn() + { + __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardNE1_TB::KeyboardOn() iKeyboardOn=%d", iKeyboardOn)); + + if (!iKeyboardOn) // may be powered up from Power Manager or HAL + { + KeyboardPowerUp(); + } + } + +void DKeyboardNE1_TB::PowerDown(TPowerState) + { + iPowerDownDfc.Enque(); // schedules DFC to execute on this driver's thread + } + +void DKeyboardNE1_TB::PowerDownDfc() + { + __KTRACE_OPT(KPOWER, Kern::Printf("DKeyboardNE1_TB::PowerDownDfc()")); + KeyboardOff(); + PowerDownDone(); // must be called from a different thread than PowerDown() + } + +void DKeyboardNE1_TB::KeyboardOff() + { + __KTRACE_OPT(KPOWER,Kern::Printf("DKeyboardNE1_TB::KeyboardOff() iKeyboardOn=%d", iKeyboardOn)); + + if (iKeyboardOn) // may have already been powered down by the HAL + { + iKeyboardOn = EFalse; + Interrupt::Disable(iIrqHandle); + } + iEventDfc.Cancel(); + } + +void DKeyboardNE1_TB::HandleMsg(TMessageBase* aMsg) + { + if (aMsg->iValue) + KeyboardOn(); + else + KeyboardOff(); + aMsg->Complete(KErrNone,ETrue); + } + +void DKeyboardNE1_TB::KeyboardInfo(TKeyboardInfoV01& aInfo) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardNE1_TB::KeyboardInfo")); + + aInfo.iKeyboardType=KConfigKeyboardType; + aInfo.iDeviceKeys=KConfigKeyboardDeviceKeys; + aInfo.iAppsKeys=KConfigKeyboardAppsKeys; + } + +TInt DKeyboardNE1_TB::HalFunction(TInt aFunction, TAny* a1, TAny* a2) + { + TInt r=KErrNone; + __KTRACE_OPT(KEXTENSION,Kern::Printf("DKeyboardNE1_TB::HalFunction %d", aFunction)); + switch(aFunction) + { + case EKeyboardHalKeyboardInfo: + { + TPckgBuf kPckg; + KeyboardInfo(kPckg()); + Kern::InfoCopy(*(TDes8*)a1,kPckg); + break; + } + case EKeyboardHalSetKeyboardState: + { + if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EKeyboardHalSetKeyboardState"))) + return KErrPermissionDenied; + if ((TBool)a1) + { + TThreadMessage& m=Kern::Message(); + m.iValue = ETrue; + m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered up + } + else + { + TThreadMessage& m=Kern::Message(); + m.iValue = EFalse; + m.SendReceive(&iMsgQ); // send a message and block Client thread until keyboard has been powered down + } + } + break; + case EKeyboardHalKeyboardState: + kumemput32(a1, &iKeyboardOn, sizeof(TBool)); + break; + default: + r=KErrNotSupported; + break; + } + return r; + } + +DECLARE_STANDARD_EXTENSION() + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Starting keyboard driver")); + + // create keyboard driver + TInt r=KErrNoMemory; + DKeyboardNE1_TB* pK=new DKeyboardNE1_TB; + if (pK) + r=pK->Create(); + + __KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r)); + return r; + } diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/specific/keymap.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/specific/keymap.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,2236 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\specific\keymap.cpp +* This file is part of the NE1_TBVariant Base port +* The keyboard lookup tables giving the function to be carried out +* and the new state of the keyboard +* +*/ + + + + +#include + +#define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0])) + + +// +// Scancode conversion tables +// -------------------------- +// The scancode conversion is arranged as a tree of tables which are used to +// convert a scancode to a keycode, taking into account the modifier state +// (shift, control, fn) +// +// How the tables work: +// -------------------- +// Firstly, there is a distinction between the "scancodes" used in scanning +// the keyboard, and the "scancodes" used in this files. +// +// Typically the keyboard driver already contains a table to convert hardware +// key location codes produced during keyboard scanning into EPOC "scancodes". +// EPOC scancodes are defined for "standard" keys like shift, backspace, +// escape, in the TStdScanCode enum (see E32KEYS.H), and should be ASCII codes +// for normal characters. The keyboard driver should add these EPOC scancodes +// to the event queue, not hardware-dependant key locations. +// +// For now on "scancode" refers to EPOC scancodes: +// +// The keyboard is divided into a number of "blocks" of contiguous scancodes +// +// Blocks map to keycodes in a keycode table, and several blocks can be +// grouped and map to a single keycode table. Blocks map into the keycode +// table in the order they are declared. For example, if two scancode blocks +// with a range of 5 scancodes map to a single 10-entry keycode table, scancodes +// which fall in the first block will map to the first 5 entries in the keycode +// table, scancodes falling in the second block map the the next 5 entries in +// the keycode table. +// +// In theory it is possible to have multiple [keycode,scancode blocks] groups +// but there is little point doing this - grouping all the scancode blocks +// with a single keycode table holding all possible keycode values is usually +// sufficient (and simpler). However, there are some special cases where this +// is useful - the most obvious example is handling of shift and caps lock. +// The shift key implies everything that the caps-lock key does (upper case +// letters) plus some shifted characters for other keys. This is done by +// defining two tables - the first handles only caps-lock (upper case), the +// second handles all other keys that are affected only by shift. If caps- +// lock is active, only the caps-lock table is used. If shift is pressed both +// the caps-lock and shift tables are scanned for the conversion. This allows +// a base table to be extended with "extras", much like deriving a class from +// base class and extending it. +// +// +// There is one or more [keycode table, scancode blocks] group for each +// modifier state - e.g. a lower-case table, upper-case, ctrl, ctrl-shift. +// This is the root of the table. +// +// When converting a scancode the key translator first obtains the correct +// conversion tables for the modifier state. It then traverses all the scancode +// blocks looking for one which contains the scancode being converted. Once +// a matching scancode range is located, the key translator maps this into +// its position in the associated keycode table to obtain the converted keycode. +// +// The key tables below appear more complicated than they really are because of +// the intermediate structures that hold pointers to other structures. The +// important structures are: +// SScanCodeBlock - contains a "start" and "end" for a scancode range +// SConvSubTable - groups a number of scanode blocks with a keycode table +// SConvTableNode - points to SConvSubTables for each modifier state +// SConvTable - the root of the translation table - points to 1..n SConvTableNode +// +// The keycode tables are just an array of TUint16. +// + + +// +// TO DO: (optional) +// +// Keys which are not affected by modifier state +// + +// +// This is a simple example of scancode to keycode mapping. The first block +// in scanCodeBlock_unmodifiable is a range of several scancodes, so maps to +// several entries in the keycode table convKeyCodes_unmodifiable. +// EStdKeyLeftShift -> maps to -> EKeyLeftShift +// EStdKeyRightShift -> maps to -> EKeyRightShift +// ... +// EStdKeyScrollLock -> maps to -> EKeyScrollLock +// +LOCAL_D const SScanCodeBlock scanCodeBlock_unmodifiable[]= + { + {EStdKeyLeftShift, EStdKeyScrollLock}, // range 1: left shift to scroll lock + }; + +LOCAL_D const TUint16 convKeyCodes_unmodifiable[]= + { + EKeyLeftShift, + EKeyRightShift, + EKeyLeftAlt, + EKeyRightAlt, + EKeyLeftCtrl, + EKeyRightCtrl, + EKeyLeftFunc, + EKeyRightFunc, + EKeyCapsLock, + EKeyNumLock, + EKeyScrollLock + }; + + + +// +// TO DO: (optional) +// +// Base conversion table +// this table traps all of the keyboard's scanCodes except those in +// convKeyCodes_unmodifiable. It appears last in the top-level table and +// is used to convert any scancode that is not converted by any of the +// other tables +// +LOCAL_D const SScanCodeBlock scanCodeBlock_base[]= + { + { EStdKeyNull, EStdKeyDownArrow }, // scancode range 1 + { '0', '9' }, // scancode range 2 + { 'A', 'Z' }, // scancode range 3 + { EStdKeyF1, EStdKeyDictaphoneRecord }, // scancode range 4 + { EStdKeyDevice0, EStdKeyDevice3 }, // scancode range 5 + }; + +LOCAL_D const TUint16 convKeyCodes_base[]= + { + EKeyNull, // scancode range 1 mapping starts here + EKeyBackspace, + EKeyTab, + EKeyEnter, + EKeyEscape, + ' ', + EKeyPrintScreen, + EKeyPause, + EKeyHome, + EKeyEnd, + EKeyPageUp, + EKeyPageDown, + EKeyInsert, + EKeyDelete, + EKeyLeftArrow, + EKeyRightArrow, + EKeyUpArrow, + EKeyDownArrow, + '0', // scancode range 2 mapping starts here + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + 'a', // scancode range 3 mapping starts here + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + EKeyF1, // scancode range 4 mapping starts here + EKeyF2, + EKeyF3, + EKeyF4, + EKeyF5, + EKeyF6, + EKeyF7, + EKeyF8, + EKeyF9, + EKeyF10, + EKeyF11, + EKeyF12, + EKeyF13, + EKeyF14, + EKeyF15, + EKeyF16, + EKeyF17, + EKeyF18, + EKeyF19, + EKeyF20, + EKeyF21, + EKeyF22, + EKeyF23, + EKeyF24, + '`', + ',', + '.', + '/', + '\\', + ';', + '\'', + '#', + '[', + ']', + '-', + '=', + '/', + '*', + '-', + '+', + EKeyEnter, + EKeyEnd, + EKeyDownArrow, + EKeyPageDown, + EKeyLeftArrow, + EKeyNull, // numeric keypad '5' + EKeyRightArrow, + EKeyHome, + EKeyUpArrow, + EKeyPageUp, + EKeyInsert, + EKeyDelete, + EKeyMenu, + EKeyBacklightOn, + EKeyBacklightOff, + EKeyBacklightToggle, + EKeyIncContrast, + EKeyDecContrast, + EKeySliderDown, + EKeySliderUp, + EKeyDictaphonePlay, + EKeyDictaphoneStop, + EKeyDictaphoneRecord, + EKeyDevice0, // scancode range 5 mapping starts here + EKeyDevice1, + EKeyDevice2, + EKeyDevice3, + }; + + +// +// TO DO: (optional) +// +// caps-lock: this table traps those scanCodes which are affected by caps-lock +// +LOCAL_D const SScanCodeBlock scanCodeBlock_capsLock[]= + { + {'A', 'Z'} // only alpha keys are affected by caps-lock + }; + +LOCAL_D const TUint16 convKeyCodes_capsLock[]= + { + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z' + }; + +// +// TO DO: (optional) +// +// shift: this table traps those scanCodes which are affected +// by normal shift key EXCEPT for those scanCodes affected by caps-lock +// + +LOCAL_D const SScanCodeBlock scanCodeBlock_shift[]= + { + {'0', '9'}, + {EStdKeyXXX, EStdKeyEquals}, + }; + +LOCAL_D const TUint16 convKeyCodes_shift[]= + { + ')', + '!', + '@',/*'"',*/ + '#', /*ELatin1Pound,*/ + '$', + '%', + '^', + '&', + '*', + '(', + '~', /*ELatin1LogicNot,*/ + '<', + '>', + '?', + '|', + ':', + '"', + '|', /*'~',*/ + '{', + '}', + '_', + '+' + }; + +// +// TO DO: (optional) +// +// func: this table traps those scanCodes which are affected +// by the func key but not shift +// +LOCAL_D const SScanCodeBlock scanCodeBlock_func[]= + { + {EStdKeyEscape, EStdKeyEscape}, + {'M', 'M'}, + {EStdKeyComma, EStdKeyComma}, + {EStdKeyLeftArrow, EStdKeyDownArrow}, + }; + +LOCAL_D const TUint16 convKeyCodes_func[]= + { + EKeyOff, + EKeyDecContrast, + EKeyIncContrast, + EKeyHome, + EKeyEnd, + EKeyPageUp, + EKeyPageDown, + }; + +// +// TO DO: (optional) +// +// func: this table traps those scanCodes which are affected +// by func and shift - this is for func pressed, shift not pressed +// +//LOCAL_D const SScanCodeBlock scanCodeBlock_funcUnshifted[]= +// { +// {'E', 'E'}, +// }; + +//LOCAL_D const TUint16 convKeyCodes_funcUnshifted[]= +// { +// ELatin1LcEacute, +// }; + +// +// TO DO: (optional) +// +// func: this table traps those scanCodes which are affected +// by func and shift - this is for func and shift both pressed +// +//LOCAL_D const SScanCodeBlock scanCodeBlock_funcShifted[]= +// { +// {'E', 'E'}, +// }; + +//LOCAL_D const TUint16 convKeyCodes_funcShifted[]= +// { +// ELatin1UcEacute, +// }; + +// +// TO DO: (optional) +// +// ctrl: this table traps those scanCodes which are affected by ctrl +// +LOCAL_D const SScanCodeBlock scanCodeBlock_ctrl[]= + { + // + // NOTE: The space key gets handled elsewhere, otherwise it gets + // thrown away as a NULL key + // {EStdKeySpace, EStdKeySpace}, + + {'A', 'Z'}, + {EStdKeyComma, EStdKeyComma}, + }; + +LOCAL_D const TUint16 convKeyCodes_ctrl[]= + { +// 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + ',', + }; + + + +// +// TO DO: (optional) +// +// Each set of scancode+keycode tables must be grouped into a SConvSubTable. +// The lines below define a number of SConvSubTables for each of the groups +// above. +// +LOCAL_D const SConvSubTable + convSubTable_unmodifiable= // table for unmodifiable keys + { + &convKeyCodes_unmodifiable[0], // the keycode table + { + ARRAY_LENGTH(scanCodeBlock_unmodifiable), // number of scancode blocks + &scanCodeBlock_unmodifiable[0] // pointer to scancode blocks + } + }, + convSubTable_base= // table for base keys + { + &convKeyCodes_base[0], // keycode table + { + ARRAY_LENGTH(scanCodeBlock_base), // number of scancode blocks + &scanCodeBlock_base[0] // pointer to scancode blocks + } + }, + convSubTable_capsLock= + { + &convKeyCodes_capsLock[0], + { + ARRAY_LENGTH(scanCodeBlock_capsLock), + &scanCodeBlock_capsLock[0] + } + }, + convSubTable_shift= + { + &convKeyCodes_shift[0], + { + ARRAY_LENGTH(scanCodeBlock_shift), + &scanCodeBlock_shift[0] + } + }, + convSubTable_func= + { + &convKeyCodes_func[0], + { + ARRAY_LENGTH(scanCodeBlock_func), + &scanCodeBlock_func[0] + } + }, +// convSubTable_funcUnshifted= +// { +// &convKeyCodes_funcUnshifted[0], +// { +// ARRAY_LENGTH(scanCodeBlock_funcUnshifted), +// &scanCodeBlock_funcUnshifted[0] +// } +// }, +// convSubTable_funcShifted= +// { +// &convKeyCodes_funcShifted[0], +// { +// ARRAY_LENGTH(scanCodeBlock_funcShifted), +// &scanCodeBlock_funcShifted[0] +// } +// }, + convSubTable_ctrl= + { + &convKeyCodes_ctrl[0], + { + ARRAY_LENGTH(scanCodeBlock_ctrl), + &scanCodeBlock_ctrl[0] + } + }; + +// +// TO DO: (optional) +// +// We need to declare arrays of SConvSubTable for each modifier state we +// are going to handle. As mentioned above, it is possible to have several +// [keycode table, scancode blocks] groups scanned for each keyboard state. +// +// Some modifier states use more than one conversion group. The simple example +// is handling of caps-lock and shift. +// +// Caps-lock means all letters are upper-case +// shift means all letters are upper case AND some other keys return control characters +// +// Obviously the shift key means everything cpas-lock means PLUS a bit more. So +// we define two tables, the caps-lock table defines only the uppercase conversion, +// and the shift table defines all OTHER shifted keys not already handled by +// caps-lock. The caps-lock modifier state then only scans the caps-lock table, and +// the shift state scans both tables. +// +LOCAL_D const SConvSubTable + * const convSubTableArray_unmodifiable[]={&convSubTable_unmodifiable}, + * const convSubTableArray_base[]={&convSubTable_base}, + + // + // The caps-lock state scans only the caps-lock table, to handle + // conversion to upper case + // + * const convSubTableArray_capsLock[]={&convSubTable_capsLock}, + // + // The shift table scans the caps-lock table to handle upper case, + // and also the shift table which handles some keys that are not affected + // by caps lock (such as 0-9). + // + * const convSubTableArray_shift[]={&convSubTable_capsLock, &convSubTable_shift}, + // + // Pressing shift with caps-lock active reverts to lower-case letters, + // but other keys remain shifted. This time we only scan the shift table + // so only the non-alpha keys will be shifted + // + * const convSubTableArray_capsLockShift[]={&convSubTable_shift}, + + // + // Like the shift/caps-lock situation, the function key has two states, + // shifted and unshifted. Also, some keys may be independant of whether + // the shift key is pressed. So there are three tables defined. One declares + // all keys that are independant of shift state, the other two tables handle + // shifted and unshifted func. + // + // Unshifted func uses the independant set + funcUnshifted + // + // * const convSubTableArray_func[]={&convSubTable_func, &convSubTable_funcUnshifted}, + * const convSubTableArray_func[]={&convSubTable_func}, + // + // Shifted func uses the independant set + funcShifted + // + // * const convSubTableArray_funcShift[]={&convSubTable_func,&convSubTable_funcShifted}, + // + // This keyboard table makes control independant of func and shift + // + * const convSubTableArray_ctrl[]={&convSubTable_ctrl}; + +// +// TO DO: (optional) +// +// This is the top of the scancode conversion tree. It is a set of pointers +// to the SConvSubTable arrays declared above. +// +// The order of these nodes is VITAL, as the scanCode/modifiers are +// searched for a match in this order +// +// The modifier state is matched by using a mask and a compare value. This is +// used as follows: +// +// match is true if ( (modifierState & mask) == compareValue +// +// For example, if the mask is (EModifierFunc|EModifierShift) and the +// compare value is EModifierFunc, this will match ANY combination of +// modifiers that has func pressed and shift not pressed +// +LOCAL_D const SConvTableNode convTableNodes[]= + { + { + { + 0, // modifier mask = no modifiers + 0 // modifier compare = no modifiers + }, + ARRAY_LENGTH(convSubTableArray_unmodifiable), // number of SConvSubTables + &convSubTableArray_unmodifiable[0] // pointer to SConvSubTable array + }, + { + { + EModifierCtrl, // modifier mask = check for ctrl + EModifierCtrl // modifier compare = anything with ctrl pressed + }, + ARRAY_LENGTH(convSubTableArray_ctrl), + &convSubTableArray_ctrl[0] + }, + { + { + // + // Check for Func pressed + // + EModifierFunc, + EModifierFunc + }, + ARRAY_LENGTH(convSubTableArray_func), + &convSubTableArray_func[0] + }, + { + { + // + // Check for caps-lock pressed, shift not pressed + // + EModifierCapsLock|EModifierShift, + EModifierCapsLock + }, + ARRAY_LENGTH(convSubTableArray_capsLock), + &convSubTableArray_capsLock[0] + }, + { + { + // + // Check for caps-lock not pressed, shift pressed + // + EModifierShift|EModifierCapsLock, + EModifierShift + }, + ARRAY_LENGTH(convSubTableArray_shift), + &convSubTableArray_shift[0] + }, + { + { + // + // Check for caps-lock pressed, shift pressed + // + EModifierCapsLock|EModifierShift, + EModifierCapsLock|EModifierShift + }, + ARRAY_LENGTH(convSubTableArray_capsLockShift), + &convSubTableArray_capsLockShift[0] + }, + { + // + // This is the base table. It must appear last so that it can + // provide a default conversion for any scancodes that are not + // handled by any of the tables above + // + { + 0, + 0 + }, + ARRAY_LENGTH(convSubTableArray_base), + &convSubTableArray_base[0] + } + }; + +// +// The top-level exported data structure of all the conversion tables +// This just points to the SConvTableNodes above +// +LOCAL_D const SConvTable ConvTable= + { + ARRAY_LENGTH(convTableNodes), + &convTableNodes[0] + }; + +// The list of scan-codes on the numeric keypad +LOCAL_D const SScanCodeBlock keypadScanCodeBlockArray[]= + { + {EStdKeyNumLock, EStdKeyNumLock}, + {EStdKeyNkpForwardSlash, EStdKeyNkpFullStop} + }; + +LOCAL_D const SScanCodeBlockList ConvTableKeypadScanCodes= + { + ARRAY_LENGTH(keypadScanCodeBlockArray), + &keypadScanCodeBlockArray[0] + }; + +// +// TO DO: (optional) +// +// List of keycodes that do not autorepeat +// +// These are usually control keys like shift, ctrl, escape +// +LOCAL_D const TUint16 nonAutorepKeyCodeArray[]= + { + EKeyEscape, + EKeyPrintScreen, + EKeyPause, + EKeyInsert, + EKeyLeftShift, + EKeyRightShift, + EKeyLeftAlt, + EKeyRightAlt, + EKeyLeftCtrl, + EKeyRightCtrl, + EKeyLeftFunc, + EKeyRightFunc, + EKeyCapsLock, + EKeyNumLock, + EKeyScrollLock, + EKeyMenu, + EKeyDictaphonePlay, + EKeyDictaphoneStop, + EKeyDictaphoneRecord + }; + +// +// TO DO: (optional) +// +// Declare blocks of non-autorepeating keycodes +// +LOCAL_D const SKeyCodeList ConvTableNonAutorepKeyCodes= + { + ARRAY_LENGTH(nonAutorepKeyCodeArray), // number of keycode arrays + &nonAutorepKeyCodeArray[0] // pointer to arrays + }; + + + + + + +// +// Keyboard state tables +// + +// What these tables do +// -------------------- +// +// These tables control the way "special" keystrokes modify the behaviour +// of the keyboard. There are two major uses for this: +// +// - handling modifier keys e.g. caps-lock, shift, alt, fn and defining +// what modifier flags are affected by these keypresses +// +// - switching the keyboard into special states (see below) +// +// Keyboard states +// --------------- +// +// Keyboard states are used to switch the keyboard into a special mode where it +// can be used to enter unusual characters. There are two uses for this: +// +// - entering numeric codes, by pressing ctrl and typing the decimal code +// - entering accented characters by pressing a key combination which +// enters "accented mode" then pressing a key. There can be multiple +// accented modes. +// +// You can see an example of accented modes on a Psion Series 5 by +// pressing Fn+Z, followed by A - this will produce an a with an umlaut (ä) +// +// These tables are also used to select simpler states such as caps-lock +// and num-lock. +// +// +// The main data structure is a SFuncTableEntry. Each of these contains +// three fields: +// +// 1. modifier match - this works the same way as the scancode conversion +// tables above, there is a mask and a compare value +// +// 2. a keycode patters - this is used to match with the keycode or keycodes +// that the state should respond to. This is a TKeyCodePattern structure +// which defines what sort of match should be performed. +// +// 3. a function and state change structure, SFuncAndState. This defines the +// state to change to, the function to perform, and a parameter for the +// function if required. +// +// TKeyCodePattern structures have two fields. The first is a keycode value +// and is only used for some match types. The second field select the type +// of match to perform: +// +// EAnyKey - match any key +// EAnyAlphaNumeric - match any alpha or numeric key +// EAnyAlpha - match any alpha key +// EAnyAlphaLowerCase - match any lower-case key +// EAnyAlphaUpperCase - match any upper-case key +// EAnyDecimalDigit - match any decimal digit +// EAnyModifierKey - match any modifier key (e.g. alt, fn, ctrl) +// EMatchKey - match if equal to keycode value in first field +// EMatchLeftOrRight - match if equal to keycode value or (keycode value + 1) +// EMatchKeyCaseInsens - like EMatchKey but perform case-insensitive comparison +// +// + +// the "array" parameter must be a true array and not a pointer +#define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0])) + +#define TABLE_ENTRY_ANOTHER_CTRL_DIGIT \ + { \ + { \ + EModifierKeyUp|EModifierFunc, \ + 0 \ + }, \ + { \ + EKeyNull, \ + EAnyDigitGivenRadix \ + }, \ + { \ + EStateCtrlDigits, \ + EAddOnCtrlDigit, \ + 0 \ + } \ + } + +// +// TO DO: (optional) +// +// This table is searched for a match if a match has not been +// found in the current state's table +// + +LOCAL_D const SFuncTableEntry defaultTable[]= + { + { + // + // prevent key up events generating keycodes + // + { + EModifierKeyUp, // mask = key up + EModifierKeyUp // match = key up - i.e. accept any key up event + }, + { + EKeyNull, // dummy value, not used + EAnyKey // accept any key + }, + { + EStateUnchanged, // state will not change + EDoNothing, // no action to perform + 0 + } + }, + { + // + // prevent any modifier key (e.g. shift, ctrl) from changing state + // + { + 0, // match any modifier state + 0 + }, + { + EKeyNull, // dummy value + EAnyModifierKey // match any modifier key + }, + { + EStateUnchanged, // don't change state + EDoNothing, // nothing to do + 0 + } + }, + { + // + // filter out any unprocessed codes + // + { + 0, // match any modifier state + 0 + }, + { + EKeyNull, // dummy value + EAnyKey // match any key + }, + { + EStateNormal, // switch back to normal keyboard state + EDoNothing, // nothing to do + 0 + } + } + }; + +// +// TO DO: (optional) +// +// This table controls which keys change which modifiers; +// NOTE: the state field in this table is ignored +// + +LOCAL_D const SFuncTableEntry modifierTable[]= + { + { + { + EModifierKeyUp, // check key-up modifier flag + 0 // make sure it's zero (i.e. ignore key-up events) + }, + { + // + // Here we want to match only the caps-lock key. We specify the + // keycode we are looking for in the first field, and EMatchKey + // in the second field + // + EKeyCapsLock, // we want to respond to caps-lock key + EMatchKey // match caps-lock only + }, + { + EStateUnchanged, // ignored + EToggleModifier, // function = toggle modifier state + EModifierCapsLock // this is the modifier to toggle + } + }, + { + { + EModifierKeyUp, + 0 + }, + { + EKeyNumLock, // this one matched num-lock + EMatchKey // match only num-lock + }, + { + EStateUnchanged, // ignored + EToggleModifier, // function = toggle modifier state + EModifierNumLock // this is the modifier to toggle + } + }, + { + { + EModifierKeyUp, + 0 + }, + { + EKeyScrollLock, // match scroll-lock key + EMatchKey + }, + { + EStateUnchanged, + EToggleModifier, // function = toggle modifier + EModifierScrollLock // modifier to toggle + } + }, + { + { + EModifierKeyUp, + 0 + }, + { + EKeyLeftAlt, // match left alt key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on a modifier + EModifierAlt|EModifierLeftAlt // alt turns on this modifier combination + } + }, + { + { + EModifierKeyUp, // goes with previous table, this handles the alt + EModifierKeyUp // key being released + }, + { + EKeyLeftAlt, // match left alt key again + EMatchKey + }, + { + EStateUnchanged, + ETurnOffModifier, // function = turn off the modifier + EModifierLeftAlt // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyLeftFunc, // match left fn key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierFunc|EModifierLeftFunc // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, this matched the + EModifierKeyUp // left-fn key up event + }, + { + EKeyLeftFunc, // match left fn key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierLeftFunc // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyLeftShift, // match left shift key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierShift|EModifierLeftShift // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, matches left shift + EModifierKeyUp // key up event + }, + { + EKeyLeftShift, // match left shift key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // turn off modifier + EModifierLeftShift // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyLeftCtrl, // match left ctrl key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierCtrl|EModifierLeftCtrl // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, matches left ctrl + EModifierKeyUp // key up event + }, + { + EKeyLeftCtrl, // match left ctrl key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierLeftCtrl // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyRightAlt, // match right alt key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierAlt|EModifierRightAlt // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, matches right alt + EModifierKeyUp // key up event + }, + { + EKeyRightAlt, // match right alt key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierRightAlt // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyRightFunc, // match right fn key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierFunc|EModifierRightFunc // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, matches right fn + EModifierKeyUp // key up event + }, + { + EKeyRightFunc, // match right fn key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierRightFunc // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyRightShift, // match right shift key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierShift|EModifierRightShift // modifier combinatoin to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, handles right shift + EModifierKeyUp // key up event + }, + { + EKeyRightShift, // match right shift key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierRightShift // modifier to turn off + } + }, + { + { + EModifierKeyUp, // key down event (key-up flag == 0) + 0 + }, + { + EKeyRightCtrl, // match right ctrl key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOnModifier, // function = turn on modifier + EModifierCtrl|EModifierRightCtrl // modifier combination to turn on + } + }, + { + { + EModifierKeyUp, // goes with above table, matched right ctrl + EModifierKeyUp // key up event + }, + { + EKeyRightCtrl, // match right ctrl key + EMatchKey + }, + { + EStateUnchanged, // ignored + ETurnOffModifier, // function = turn off modifier + EModifierRightCtrl // modifier to turn off + } + } + }; + + +// +// TO DO: (optional) +// +// Tables corresponding to keyboard states. +// +// There are 13 keyboard states. States 0 to 9 can be used to create alternative +// keyboard layouts for entering accented or unusual characters. Switching into +// these states is done by a keypress. Implementation of the states is optional +// depending on how many special state you want - you may implement 10 states, +// you might decide not to implement any. +// +// State 10 is the normal state. The table for state 10 defines which keypresses +// change to other states. +// +// States 11 and 12 are used when entering the numeric code of a character. State +// 11 is for entering a specific number of digits. State 12 is for accepting +// digits until Ctrl is released. +// +// +// As before, each SFuncTableEntry entry defines: +// - modifier conditions that must be matched +// - a keycode match pattern (typically an exact key match) +// - the function to perform and new state +// +// Switching into states 0..9,11,12 is done by entries in table10 +// + +//LOCAL_D const SFuncTableEntry table0[]= +// { +// TABLE_ENTRY_ANOTHER_CTRL_DIGIT +// }; + +LOCAL_D const SFuncTableEntry table1[]= + { + // + // Table for special keyboard state 1 + // This state is entered by pressing Fn+q (see table10) + // + // The table makes certain keys return accented characters + // + { + { + // + // Function must be release, and this must be a key down event + // + EModifierFunc|EModifierKeyUp, + 0 + }, + { + // + // match an 'e' keypress, convert to an ae ligature (æ) + // + 'e', + EMatchKeyCaseInsens + }, + { + EStateNormal, // switch back to state normal (table10) + EPassSpecialKeyThru, // turn keypress into a special character + ELatin1LcAe // this is the character to pass on + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'c', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcCcedilla + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 's', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1EsTset + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOslash + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'd', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcThorn + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 't', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcSoftTh + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'l', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LeftChevron + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'r', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1RightChevron + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'x', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1InvExclam + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'q', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1InvQuest + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAo + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'p', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1Pound + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +LOCAL_D const SFuncTableEntry table2[]= + { + // + // Table for special keyboard state 2 + // This state is entered by pressing Fn+z (see table10) + // + // The table makes certain keys return accented characters + // See table1 for an explanation of the contents + // + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'e', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcEumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'i', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcIumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'u', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcUumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'y', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcYumlaut + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + ' ', + EMatchKey + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1SpaceUmlaut + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +LOCAL_D const SFuncTableEntry table3[]= + { + // + // Table for special keyboard state 3 + // This state is entered by pressing Fn+x (see table10) + // + // The table makes certain keys return accented characters + // + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAgrave + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'e', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcEgrave + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'i', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcIgrave + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOgrave + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'u', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcUgrave + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + ' ', + EMatchKey + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1SpaceGrave + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +LOCAL_D const SFuncTableEntry table4[]= + { + // + // Table for special keyboard state 4 + // This state is entered by pressing Fn+c (see table10) + // + // The table makes certain keys return accented characters + // + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'e', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcEacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'i', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcIacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'u', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcUacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'y', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcYacute + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + ' ', + EMatchKey + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcSpaceAcute + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +LOCAL_D const SFuncTableEntry table5[]= + { + // + // Table for special keyboard state 5 + // This state is entered by pressing Fn+v (see table10) + // + // The table makes certain keys return accented characters + // + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAtilde + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'n', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcNtilde + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOtilde + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + ' ', + EMatchKey + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcSpaceTilde + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +LOCAL_D const SFuncTableEntry table6[]= + { + // + // Table for special keyboard state 6 + // This state is entered by pressing Fn+b (see table6) + // + // The table makes certain keys return accented characters + // + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'a', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcAcirc + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'e', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcEcirc + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'i', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcIcirc + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'o', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcOcirc + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + 'u', + EMatchKeyCaseInsens + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcUcirc + } + }, + { + { + EModifierFunc|EModifierKeyUp, + 0 + }, + { + ' ', + EMatchKey + }, + { + EStateNormal, + EPassSpecialKeyThru, + ELatin1LcSpaceCirc + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + +// +// TO DO: (optional) +// +// State 7,8,9 aren't used in this example. +// You can implement them if you want more special states +// + +//LOCAL_D const SFuncTableEntry table7[]= +// { +// TABLE_ENTRY_ANOTHER_CTRL_DIGIT +// }; + +//LOCAL_D const SFuncTableEntry table8[]= +// { +// TABLE_ENTRY_ANOTHER_CTRL_DIGIT +// }; + +//LOCAL_D const SFuncTableEntry table9[]= +// { +// TABLE_ENTRY_ANOTHER_CTRL_DIGIT +// }; + + +LOCAL_D const SFuncTableEntry table10[]= + { + // + // TO DO: (optional) + // + // Table keyboard state 10 - the normal state + // + // This table controls which keys switch into the special states + // 0-9, 11 and 12. + // + + { + // + // Make sure key-up events are ignored by handling them first and + // doing nothing + // + { + EModifierKeyUp, + EModifierKeyUp + }, + { + EKeyNull, + EAnyKey + }, + { + EStateUnchanged, + EDoNothing, + 0 + } + }, + { + // + // Check for ctrl-number presses + // This will enter state EStateCtrlDigits (state 12) which allows + // entry of a numeric keycode + // + { + EModifierCtrl|EModifierFunc|EModifierKeyUp, + EModifierCtrl + }, + { + EKeyNull, + EAnyDecimalDigit + }, + { + EStateDerivedFromDigitEntered, + EAddOnCtrlDigit, + 0 + } + }, + { + // + // Any other key events that have not been trapped are just + // passed through unchanged + // + { + 0, + 0 + }, + { + EKeyNull, + EAnyKey + }, + { + EStateUnchanged, + EPassKeyThru, + 0 + } + } + }; + +//LOCAL_D const SFuncTableEntry table11[]= +// { +// TABLE_ENTRY_ANOTHER_CTRL_DIGIT +// }; + +LOCAL_D const SFuncTableEntry table12[]= + { + // + // Table 12 handles entring digit codes. The keyboard will remain in this + // state until the Ctrl key is released + // + { + { + // + // Look for a key up event + // + EModifierKeyUp, + EModifierKeyUp + }, + { + // + // Match either left or right Ctrl key (i.e. this matches a Ctrl key release) + // + EKeyLeftCtrl, + EMatchLeftOrRight + }, + { + EStateNormal, // return to normal state (table10) + EPassCtrlDigitsThru, // and pass through the numeric code we have accumulated + 0 + } + }, + TABLE_ENTRY_ANOTHER_CTRL_DIGIT + }; + + +// +// TO DO: (optional) +// +// Array of state control tables above. If a state is not used set the array +// size to zero and the pointer to NULL +// +// The tables must be declared here in order from table 0 to table 12 +// +LOCAL_D const SFuncTable genFuncTables[]= + { + { + // + // state 0 + // + 0, // state 0 not used, size = 0 + NULL // state 0 not used, pointer = NULL + }, + { + // + // state 1 + // + ARRAY_LENGTH(table1), // size of table 1 + &table1[0] // pointer to table 1 + }, + { + // + // state 2 + // + ARRAY_LENGTH(table2), + &table2[0] + }, + { + // + // state 3 + // + ARRAY_LENGTH(table3), + &table3[0] + }, + { + // + // state 4 + // + ARRAY_LENGTH(table4), + &table4[0] + }, + { + // + // state 5 + // + ARRAY_LENGTH(table5), + &table5[0] + }, + { + // + // state 6 + // + ARRAY_LENGTH(table6), + &table6[0] + }, + { + // + // state 7 + // + 0, + NULL + }, + { + // + // state 8 + // + 0, + NULL + }, + { + // + // state 9 + // + 0, + NULL + }, + { + // + // state 10 + // + ARRAY_LENGTH(table10), + &table10[0] + }, + { + // + // state 11 + // + 0, + NULL + }, + { + // + // state 12 + // + ARRAY_LENGTH(table12), + &table12[0] + } + }; + + +// +// Root of the state modifier tables +// +LOCAL_D const SFuncTables FuncTables= + { + { + // + // The default processing table + // + ARRAY_LENGTH(defaultTable), + &defaultTable[0] + }, + { + // + // The modifier control table + // + ARRAY_LENGTH(modifierTable), + &modifierTable[0] + }, + // + // The state control tables + // + ARRAY_LENGTH(genFuncTables), + &genFuncTables[0] + }; + + +// +// The following exported functions give the key translator access to +// the control tables above +// +EXPORT_C void KeyDataSettings(TRadix &aRadix,TCtrlDigitsTermination &aCtrlDigitsTermination,TInt &aDefaultCtrlDigitsMaxCount, + TInt &aMaximumCtrlDigitsMaxCount) + { + aRadix=EDecimal; + aCtrlDigitsTermination=ETerminationByCtrlUp; + aDefaultCtrlDigitsMaxCount=3; + aMaximumCtrlDigitsMaxCount=10; + } + +EXPORT_C void KeyDataFuncTable(SFuncTables &aFuncTables) + { + aFuncTables=FuncTables; + } + +EXPORT_C void KeyDataConvTable(SConvTable &aConvTable, TUint &aConvTableFirstScanCode,TUint &aConvTableLastScanCode, + SScanCodeBlockList &aKeypadScanCode,SKeyCodeList &aNonAutorepKeyCodes) + { + aConvTable=ConvTable; + aConvTableFirstScanCode=scanCodeBlock_base[0].firstScanCode; + aConvTableLastScanCode=scanCodeBlock_base[ARRAY_LENGTH(scanCodeBlock_base)-1].lastScanCode; + aKeypadScanCode=ConvTableKeypadScanCodes; + aNonAutorepKeyCodes=ConvTableNonAutorepKeyCodes; + } diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/specific/keypad.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/specific/keypad.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,254 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\specific\keypad.cpp +* This file contains the implementation of Keypad for the NEC LCD. +* +*/ + + + +#include +#include +#include +#include +#include +#include "lcdgce.h" + + +// =-==LCD keypad settings and registers================== +const TUint KKeybPollTime = 100; +const TUint KHWKeyRL = KHwFPGABase + 0x0410; // Key return line +const TUint KHWKeySR = KHwFPGABase + 0x0418; // Key scan register + +// Scan codes for buttons: (scan_register_value | (1<ProcessKey(KHwKeyNumArrowUp, ((key & KHwKeyCodeArrowUp )==KHwKeyCodeArrowUp )); + pD->ProcessKey(KHwKeyNumArrowRight, ((key & KHwKeyCodeArrowRight )==KHwKeyCodeArrowRight )); + pD->ProcessKey(KHwKeyNumArrowLeft, ((key & KHwKeyCodeArrowLeft )==KHwKeyCodeArrowLeft )); + pD->ProcessKey(KHwKeyNumArrowDown, ((key & KHwKeyCodeArrowDown )==KHwKeyCodeArrowDown )); + pD->ProcessKey(KHwKeyNumButtonCentre, ((key & KHwKeyCodeButtonCentre)==KHwKeyCodeButtonCentre)); + pD->ProcessKey(KHwKeyNumButtonLeft, ((key & KHwKeyCodeButtonLeft )==KHwKeyCodeButtonLeft )); + pD->ProcessKey(KHwKeyNumButtonRight, ((key & KHwKeyCodeButtonRight )==KHwKeyCodeButtonRight )); + + pD->iKeyboardTimer.Again(KKeybPollTime); + } + +DNE1Keypad::DNE1Keypad() : + iKeyboardTimer(GetScanCodes, this), + iKeyStates(0) + { + TUint idMode = AsspRegister::Read32(KHwIDMODE); + TUint keyMode = (idMode & KHmKeyConfigSwitch) >> KHsKeyConfigSwitch; + + switch (keyMode) + { + default: + case 0: iKeyMode = EKeyModeTechview; break; + case 1: iKeyMode = EKeyModeS60; break; + } + } + +TInt DNE1Keypad::DoCreate() + { + iKeyboardTimer.OneShot(KKeybPollTime, ETrue); + return KErrNone; + } + + +DECLARE_STANDARD_EXTENSION() + { + // check the display mode - and if LCD is not on + // (any of ANALOG modes is set)- do not create/start the driver.. + TInt r = KErrNoMemory; + TInt mode = ReadDipSwitchDisplayMode(); + if(mode == DISPLAY_MODE_ANALOG_VGA || + mode == DISPLAY_MODE_ANALOG_QVGA_LANDSCAPE_OLD || + mode == DISPLAY_MODE_ANALOG_QVGA_PORTRAIT || + mode == DISPLAY_MODE_ANALOG_QVGA_LANDSCAPE) + { + __KTRACE(Kern::Printf("keypad.cpp: LCD panel not switched on...\nwill not start the driver")); + r = KErrNone; // just return.. + } + else + { + DNE1Keypad* pD= new DNE1Keypad; + if (pD) + r = pD->DoCreate(); + } + + return r; + } diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/specific/lffsdev.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/specific/lffsdev.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,670 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\Specific\lffsdev.cpp +* Implementation of a Logging Flash file system (LFFS) physical device driver +* for a standard Common Flash Interface (CFI) based NOR flash chip. +* This file is part of the NE1_TBVariant Base port +* N.B. This sample code assumes that: +* (1) the device does not provide an interrupt i.e. it needs to be polled using a timer +* to ascertain when an Erase/Write operation has completed. +* (2) the flash chip does not have 'read-while-write' support. +* +*/ + + + +#include "lffsdev.h" +#include "variant.h" + +#ifdef _DEBUG +#define CHANGE_ERASE_STATE(x) {TUint32 s=iEraseState; iEraseState=x; __KTRACE_OPT(KLOCDRV,Kern::Printf("ErSt: %d->%d",s,x));} +#else +#define CHANGE_ERASE_STATE(x) iEraseState=x +#endif + +// +// TO DO: (mandatory) +// +// Define the pyhsical base address of the NOR-Flash +// This is only example code... you will need to modify it for your hardware +const TPhysAddr KFlashPhysicalBaseAddress = 0x04000000; + + +/******************************************** + * Common Flash Interface (CFI) query stuff + ********************************************/ + +/** +Read an 8-bit value from the device at the specified offset + +@param aOffset the address in device words +*/ +TUint32 DMediaDriverFlashNE1_TB::ReadQueryData8(TUint32 aOffset) + { + volatile TUint8* pF=(volatile TUint8*)(iBase+FLASH_ADDRESS_IN_BYTES(aOffset)); + return pF[0]; + } + +/** +Read a 16-bit value from the device at the specified offset + +@param aOffset the address in device words +*/ +TUint32 DMediaDriverFlashNE1_TB::ReadQueryData16(TUint32 aOffset) + { + volatile TUint8* pF=(volatile TUint8*)(iBase); + return + pF[FLASH_ADDRESS_IN_BYTES(aOffset+0)] | + (pF[FLASH_ADDRESS_IN_BYTES(aOffset+1)] << 8); + } + +/** + Put the device into query mode to read the flash parameters. + */ +void DMediaDriverFlashNE1_TB::ReadFlashParameters() + { + volatile TFLASHWORD* pF=(volatile TFLASHWORD*)iBase + KCmdReadQueryOffset; + *pF=KCmdReadQuery; + + TUint32 qd=ReadQueryData16(KQueryOffsetQRY)|(ReadQueryData8(KQueryOffsetQRY+2)<<16); + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:Query QRY=%08x",qd)); + __ASSERT_ALWAYS(qd==0x595251,FLASH_FAULT()); + + qd = FLASH_BUS_DEVICES << ReadQueryData8(KQueryOffsetSizePower); + + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:Query Size=%08x",qd)); + iTotalSize=qd; + + qd = FLASH_BUS_DEVICES << ReadQueryData16(KQueryOffsetWriteBufferSizePower); + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:Query WBSize=%08x",qd)); + iWriteBufferSize=qd; + + qd = (ReadQueryData16(KQueryOffsetEraseBlockSize)) << (8 + FLASH_BUS_DEVICES-1); + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:Query EBSize=%08x",qd)); + iEraseBlockSize=qd; + + *pF=KCmdReadArray; + } + + +/******************************************** + * Common Flash Interface (CFI) main code + ********************************************/ + +/** +NOR flash LFFS constructor. + +@param aMediaId Media id number from ELOCD +*/ +DMediaDriverFlashNE1_TB::DMediaDriverFlashNE1_TB(TInt aMediaId) + : DMediaDriverFlash(aMediaId), + iHoldOffTimer(HoldOffTimerFn,this), + iEventDfc(EventDfc,this,NULL,2) + { + // iWriteState = EWriteIdle; + // iEraseState = EEraseIdle; + } + +/** +Device specific implementation of the NOR LFFS initialisation routine. + +@see DMediaDriverFlash::Initialise +@return KErrNone unless the write data buffer couldn't be allocated or the + timer interrupt could not be bound. + */ +TInt DMediaDriverFlashNE1_TB::Initialise() + { + iEventDfc.SetDfcQ(iPrimaryMedia->iDfcQ); + iData=(TUint8*)Kern::Alloc(KDataBufSize); + if (!iData) + return KErrNoMemory; + + // Create temporary HW chunk to read FLASH device parameters (especially size) + DPlatChunkHw* pC = NULL; + TInt r = DPlatChunkHw::New(pC, KFlashPhysicalBaseAddress, 0x1000, EMapAttrSupRw|EMapAttrFullyBlocking); + if (r!=KErrNone) + return r; + iBase = pC->LinearAddress(); + ReadFlashParameters(); + // close temporary chunk and open chunk with correct size + pC->Close(NULL); + r = DPlatChunkHw::New(iFlashChunk, KFlashPhysicalBaseAddress, iTotalSize, EMapAttrSupRw|EMapAttrFullyBlocking); + if (r!=KErrNone) + return r; + iBase = iFlashChunk->LinearAddress(); + + r=Interrupt::Bind(KIntIdTimer1, Isr, this); + if (r<0) + { + __KTRACE_OPT(KLOCDRV, Kern::Printf("Flash:Isr Bind failed")); + return r; + } + + // TO DO: (mandatory) + // Write to the appropriate hardware register(s) to + // configure (if necessary) and enable the timer hardware + // + + // Enable the timer interrupt + Interrupt::Enable(r); + + return KErrNone; + } + +/** +Used by the generic flash media driver code to get the erase block size in +bytes. + */ +TUint32 DMediaDriverFlashNE1_TB::EraseBlockSize() + { + return iEraseBlockSize; + } + +/** +@return Return size of lffs in bytes +*/ +TUint32 DMediaDriverFlashNE1_TB::TotalSize() + { + return iTotalSize; + } + +/** +Read at the location indicated by DMediaDriverFlash::iReadReq. +Where Pos() is the read location + +@return >0 Defer request to ELOCD. A write is in progress +@return KErrNone Erase has been started +@return <0 An error has occured. +*/ +TInt DMediaDriverFlashNE1_TB::DoRead() + { + if (iWriteReq) + return KMediaDriverDeferRequest; // write in progress so defer read + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:DoRead")); + if (iEraseState==EEraseIdle || iEraseState==ESuspended) + { + // can do the read now + TInt pos=(TInt)iReadReq->Pos(); + TInt len=(TInt)iReadReq->Length(); + + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:DoRead ibase: %x, pos: %x, len: %x",iBase,pos,len)); + + // Issue a read array command + // Porting note: Some devices may work without this step. + // Ensure that the write is always dword aligned + volatile TFLASHWORD* pF=(volatile TFLASHWORD*)((iBase+pos)&0xFFFFFFF0); + *pF=KCmdReadArray; + + TPtrC8 des((const TUint8*)(iBase+pos),len); + TInt r=iReadReq->WriteRemote(&des,0); + Complete(EReqRead,r); + + // resume erase if necessary + if (iEraseState==ESuspended) + StartErase(); + } + else if (iEraseState==EErase) + { + // erase in progress - suspend it + SuspendErase(); + } + else if (iEraseState==EEraseNoSuspend) + CHANGE_ERASE_STATE(ESuspendPending); // wait for suspend to complete + + + return KErrNone; + } + +/** +Write at the location indicated by DMediaDriverFlash::iWriteReq + +@return >0 Defer request to ELOCD. A read is in progress +@return KErrNone Erase has been started +@return <0 An error has occured. + */ +TInt DMediaDriverFlashNE1_TB::DoWrite() + { + if (iReadReq) + return KMediaDriverDeferRequest; // read in progress so defer write + + TInt pos=(TInt)iWriteReq->Pos(); + TInt len=(TInt)iWriteReq->Length(); + if (len==0) + return KErrCompletion; + TUint32 wb_mask=iWriteBufferSize-1; + iWritePos=pos & ~wb_mask; // round media position down to write buffer boundary + TInt wb_off=pos & wb_mask; // how many bytes of padding at beginning + TInt start_len=Min(len,KDataBufSize-(TInt)wb_off); + TInt write_len=(start_len+wb_off+wb_mask)&~wb_mask; + memset(iData,0xff,iWriteBufferSize); + memset(iData+write_len-iWriteBufferSize,0xff,iWriteBufferSize); + TPtr8 des(iData+wb_off,0,start_len); + TInt r=iWriteReq->ReadRemote(&des,0); + if (r!=KErrNone) + return r; + iWriteReq->RemoteDesOffset()+=start_len; + iWriteReq->Length()-=start_len; + iDataBufPos=0; + iDataBufRemain=write_len; + iWriteError=KErrNone; + + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:Write iWritePos=%08x iDataBufRemain=%x",iWritePos,iDataBufRemain)); + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:Write Pos=%08x Length=%08x RemDesOff=%08x", + (TInt)iWriteReq->Pos(),(TInt)iWriteReq->Length(),iWriteReq->RemoteDesOffset())); + + if (iEraseState==EEraseIdle || iEraseState==ESuspended) + { + // can start the write now + iWriteState=EWriting; + WriteStep(); + } + else if (iEraseState==EErase) + { + // erase in progress - suspend it + SuspendErase(); + } + else if (iEraseState==EEraseNoSuspend) + CHANGE_ERASE_STATE(ESuspendPending); // wait for suspend to complete + + return KErrNone; + } + +void DMediaDriverFlashNE1_TB::WriteStep() + { + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:WriteStep @%08x",iWritePos)); + if (iDataBufRemain) + { + // still data left in buffer + volatile TFLASHWORD* pF=(volatile TFLASHWORD*)(iBase+iWritePos); + TInt i=KMaxWriteSetupAttempts; + *pF=KCmdClearStatusRegister; + TUint32 s=0; + for (; i>0 && ((s&KStsReady)!=KStsReady); --i) + { + *pF=KCmdWriteToBuffer; // send write command + *pF=KCmdReadStatusRegister; // send read status command + s=*pF; // read status reg + } + __KTRACE_OPT(KLOCDRV,Kern::Printf("i=%d, s=%08x",i,s)); + + // calculate the buffer size in words -1 + TFLASHWORD l = (FLASH_BYTES_TO_WORDS(iWriteBufferSize)) - 1; + +#if FLASH_BUS_DEVICES == 2 // 2x16bit or 2x8bit devices + l|= l<< BUS_WIDTH_PER_DEVICE; +#elif FLASH_BUS_DEVICES == 4 // 4x8bit device + l|= (l<=0; len--) + { + *pF++=*pS++; + } + + *(volatile TFLASHWORD *)(iBase+iWritePos) = KCmdConfirm; + + // set up timer to poll for completion + StartPollTimer(KFlashWriteTimerPeriod,KFlashWriteTimerRetries); + + iWritePos+=iWriteBufferSize; + iDataBufPos+=iWriteBufferSize; + iDataBufRemain-=iWriteBufferSize; + if (!iDataBufRemain) + { + // refill buffer + TInt len=(TInt)iWriteReq->Length(); + if (!len) + return; // all data has been written, complete request next time + TUint32 wb_mask=iWriteBufferSize-1; + TInt block_len=Min(len,KDataBufSize); + TInt write_len=(block_len+wb_mask)&~wb_mask; + memset(iData+write_len-iWriteBufferSize,0xff,iWriteBufferSize); + TPtr8 des(iData,0,block_len); + TInt r=iWriteReq->ReadRemote(&des,0); + if (r!=KErrNone) + { + iWriteError=r; + return; // leave iDataBufRemain=0 so request is terminated when write completes + } + iWriteReq->RemoteDesOffset()+=block_len; + iWriteReq->Length()-=block_len; + iDataBufPos=0; + iDataBufRemain=write_len; + } + } + else + { + // write request should have completed, maybe with an error + __ASSERT_ALWAYS(iWriteReq->Length()==0 || iWriteError,FLASH_FAULT()); + iWriteState=EWriteIdle; + Complete(EReqWrite,iWriteError); + if (iEraseState==ESuspended) + StartErase(); + } + } + +/** +Erase at the location indicated by DMediaDriverFlash::iEraseReq + +@return >0 Defer request to ELOCD. Read or a write is in progress +@return KErrNone Erase has been started +@return <0 An error has occured. + */ +TInt DMediaDriverFlashNE1_TB::DoErase() + { + if (iReadReq || iWriteReq) + return KMediaDriverDeferRequest; // read or write in progress so defer this request + TUint32 pos=(TUint32)iEraseReq->Pos(); + TUint32 len=(TUint32)iEraseReq->Length(); + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:DoErase %d@%08x",len,pos)); + if (len!=iEraseBlockSize) + return KErrArgument; // only allow single-block erase + if (pos & (iEraseBlockSize-1)) + return KErrArgument; // start position must be on erase block boundary + iErasePos=pos; + __ASSERT_ALWAYS(iEraseState==EEraseIdle,FLASH_FAULT()); + StartErase(); + return KErrNone; + } + +void DMediaDriverFlashNE1_TB::StartHoldOffTimer() + { + // if this is a retry, don't allow suspends + if (iEraseAttempt==0) + iHoldOffTimer.OneShot(KEraseSuspendHoldOffTime); + } + +void DMediaDriverFlashNE1_TB::CancelHoldOffTimer() + { + iHoldOffTimer.Cancel(); + ClearEvents(EHoldOffEnd); + } + +void DMediaDriverFlashNE1_TB::ClearEvents(TUint32 aEvents) + { + __e32_atomic_and_ord32(&iEvents, ~aEvents); + } + +void DMediaDriverFlashNE1_TB::HoldOffTimerFn(TAny* aPtr) + { + DMediaDriverFlashNE1_TB* p=(DMediaDriverFlashNE1_TB*)aPtr; + p->IPostEvents(EHoldOffEnd); + } + +void DMediaDriverFlashNE1_TB::StartPollTimer(TUint32 aPeriod, TUint32 aRetries) + { + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:Tmr %d * %d",aPeriod,aRetries)); + + ClearEvents(EPollTimer); + iPollPeriod=aPeriod; + iPollRetries=aRetries; + StartPollTimer(); + } + +void DMediaDriverFlashNE1_TB::StartPollTimer() + { + // TO DO: (mandatory) + // Configure the hardware timer to expire after iPollPeriod ticks + // and start the timer + + } + +void DMediaDriverFlashNE1_TB::EventDfc(TAny* aPtr) + { + DMediaDriverFlashNE1_TB* p=(DMediaDriverFlashNE1_TB*)aPtr; + TUint32 e = __e32_atomic_swp_ord32(&p->iEvents, 0); + if (e) + p->HandleEvents(e); + } + +void DMediaDriverFlashNE1_TB::HandleEvents(TUint32 aEvents) + { + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:Events %x",aEvents)); + if (aEvents & EHoldOffEnd) + { + if (iEraseState==ESuspendPending) + { + SuspendErase(); + } + else if (iEraseState==EEraseNoSuspend) + { + CHANGE_ERASE_STATE(EErase); // can now be suspended + } + else + { + __KTRACE_OPT(KPANIC,Kern::Printf("iEraseState=%d",iEraseState)); + FLASH_FAULT(); + } + } + if (aEvents & EPollTimer) + { + volatile TFLASHWORD* pF=(volatile TFLASHWORD*)iBase; + *pF=KCmdReadStatusRegister; + if ((*pF & KStsReady)!=KStsReady) + { + // not ready yet + if (--iPollRetries) + { + // try again + StartPollTimer(); + } + else + // timed out + aEvents|=ETimeout; + } + else + { + // ready + TFLASHWORD s=*pF; // read full status value + *pF=KCmdClearStatusRegister; + DoFlashReady(s); + } + } + if (aEvents & ETimeout) + { + DoFlashTimeout(); + } + } + +void DMediaDriverFlashNE1_TB::StartErase() + { + TFLASHWORD s=KStsReady; + TInt i; + volatile TFLASHWORD* pF=(volatile TFLASHWORD*)(iBase+iErasePos); + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:StartErase %08x",pF)); + switch (iEraseState) + { + case EEraseIdle: // first attempt to erase + iEraseAttempt=-1; + // Fall-through + case EErase: // retry after verify failed + case EEraseNoSuspend: + ++iEraseAttempt; + *pF=KCmdBlockErase; + *pF=KCmdConfirm; + CHANGE_ERASE_STATE(EEraseNoSuspend); + iEraseError=0; + StartHoldOffTimer(); + break; + case ESuspended: + *pF=KCmdClearStatusRegister; + *pF=KCmdEraseResume; + CHANGE_ERASE_STATE(EEraseNoSuspend); + i=KMaxEraseResumeAttempts; + for (; i>0 && ((s&KStsReady)!=0); --i) + { + *pF=KCmdReadStatusRegister; // send read status command + s=*pF; // read status reg + s=*pF; // read status reg + } + __KTRACE_OPT(KLOCDRV,Kern::Printf("RESUME: i=%d, s=%08x",i,s)); + StartHoldOffTimer(); + break; + default: + __KTRACE_OPT(KPANIC,Kern::Printf("iEraseState=%d",iEraseState)); + FLASH_FAULT(); + } + StartPollTimer(KFlashEraseTimerPeriod,KFlashEraseTimerRetries); + } + +void DMediaDriverFlashNE1_TB::SuspendErase() + { + __ASSERT_ALWAYS(iEraseState==EErase || iEraseState==ESuspendPending,FLASH_FAULT()); + volatile TFLASHWORD* pF=(volatile TFLASHWORD*)(iBase+iErasePos); + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:SuspendErase %08x",pF)); + *pF=KCmdEraseSuspend; + CHANGE_ERASE_STATE(ESuspending); + StartPollTimer(KFlashSuspendTimerPeriod,KFlashSuspendTimerRetries); + } + +void DMediaDriverFlashNE1_TB::StartPendingRW() + { + // start any pending read or write requests + if (iReadReq) + DoRead(); + if (iWriteReq) + { + // can start the write now + iWriteState=EWriting; + WriteStep(); + } + } + +void DMediaDriverFlashNE1_TB::DoFlashReady(TUint32 aStatus) + { + // could be write completion, erase completion or suspend completion + if (iWriteState==EWriting) + { + // write completion + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:WriteComplete %08x",aStatus)); + TUint32 err=aStatus & (KStsWriteError|KStsVppLow|KStsLocked); + if (err) + { + iWriteState=EWriteIdle; + Complete(EReqWrite,KErrGeneral); + if (iEraseState==ESuspended) + StartErase(); + } + else + WriteStep(); + return; + } + + // put the FLASH back into read mode + volatile TFLASHWORD* pF=(volatile TFLASHWORD*)(iBase+iErasePos); + *pF=KCmdReadArray; + + if (iEraseState==ESuspending) + { + // erase suspend completion + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:SuspendComplete %08x",aStatus)); + + // accumulate errors during erase + iEraseError|=(aStatus & (KStsEraseError|KStsVppLow|KStsLocked)); + + if (aStatus & KStsSuspended) + { + // at least one of the two FLASH devices has suspended + CHANGE_ERASE_STATE(ESuspended); + + // start any pending read or write requests + StartPendingRW(); + return; // in case erase has been resumed by DoRead() + } + + // erase completed before we suspended it + CHANGE_ERASE_STATE(EErase); + } + if (iEraseState==EErase || iEraseState==EEraseNoSuspend) + { + // erase completion + __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:EraseComplete %08x",aStatus)); + CancelHoldOffTimer(); + + // accumulate errors during erase + iEraseError|=(aStatus & (KStsEraseError|KStsVppLow|KStsLocked)); + + TFLASHWORD x = FLASH_ERASE_WORD_VALUE; + + // if no device error, verify that erase was successful + if (!iEraseError) + { + volatile TFLASHWORD* p=pF; + volatile TFLASHWORD* pE=p + FLASH_BYTES_TO_WORDS(iEraseBlockSize); + while(p +#include "variant.h" +#include "uart/uart16550_ne.h" + +// A copy of TNaviEngine::DoDebugOutput +static TUint DebugPortAddr() + { + TUint debugPort; + switch (Kern::SuperPage().iDebugPort) + { + case Arm::EDebugPortJTAG: debugPort = 0; break; //indicates JTAG debugging + case 0x101: + case 1: debugPort=KHwBaseUart1; break; + case 2: debugPort=KHwBaseUart2; break; + default: debugPort=KHwBaseUart0; break; + } + return debugPort; + } + + +// +// UART code +// +void CrashDebugger::InitUart() + { + // Initialise the UART for standard debug output + TUint32 baseAddr = DebugPortAddr(); + if (baseAddr) // baseAddr is NULL in case of jtag logging + { + TUint32 dp = Kern::SuperPage().iDebugPort; + TBool highSpeed = (dp==0x100 || dp==0x101); + + // Baud Rate = 115200; 8 bits, no parity, 1 stop bit + *((volatile TInt*) (baseAddr+K16550LCROffset)) = 0x83; + *((volatile TInt*) (baseAddr+K16550BDLoOffset)) = highSpeed ? KBaudRateDiv_230400 : KBaudRateDiv_default; + *((volatile TInt*) (baseAddr+K16550BDHiOffset)) = 0; + *((volatile TInt*) (baseAddr+K16550LCROffset)) = 3; + + // Set the FIFO control register (FCR) to polled mode & don't use interrupts + *((volatile TInt*) (baseAddr+K16550FCROffset)) = 0; + *((volatile TInt*) (baseAddr+K16550FCROffset)) = 1; + *((volatile TInt*) (baseAddr+K16550IEROffset)) = 0; + } + } + +void CrashDebugger::UartOut(TUint aChar) + { + TUint debugPort = DebugPortAddr(); + volatile TUint32& LSR = *(volatile TUint32*)(debugPort + 0x14); + volatile TUint32& TXHR = *(volatile TUint32*)(debugPort + 0x00); + volatile TUint32& RXHR = *(volatile TUint32*)(debugPort + 0x00); + while (LSR & 1) + { + if (CheckPower()) + return; + TUint32 c = RXHR; + if (c==19) // XOFF + { + FOREVER + { + // wait for XON + while (!(LSR & 1)) + { + if (CheckPower()) + return; + } + c = RXHR; + if (c==17) // XON + break; + else if (c==3) // Ctrl C + Leave(KErrCancel); + } + } + else if (c==3) // Ctrl C + Leave(KErrCancel); + } + while (!(LSR & 32)) + CheckPower(); + TXHR = aChar; + } + +TUint8 CrashDebugger::UartIn() + { + TUint debugPort = DebugPortAddr(); + volatile TUint32& LSR = *(volatile TUint32*)(debugPort + 0x14); + volatile TUint32& RXHR = *(volatile TUint32*)(debugPort + 0x00); + while (!(LSR & 1)) + { + if (CheckPower()) + return (TUint8)0x0d; + } + return (TUint8)RXHR; + } + +TBool CrashDebugger::CheckPower() + { + // + // TO DO: (mandatory) + // + // Check if power supply is stable and return ETrue if not + // + return EFalse; // EXAMPLE ONLY + } + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/specific/power.cia --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/specific/power.cia Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\specific\power.cia +* NE1_TBVariant Power Management +* +*/ + + + +#ifdef __SMP__ + +#include +#include "ne1_tb_power.h" +#include +#include + +__NAKED__ TInt DNE1_TBPowerController::ClearTimerInterrupt() + { + asm("ldr r1, __KHwTimersBase "); // Base address of timer 0 + asm("mov r2, #%a0" : : "i" ((TInt)KNETimerGTIInt_TCI)); + asm("str r2, [r1, #%a0]" : : "i" _FOFF(NETimer,iGTInterrupt)); // clear interrupt + asm("ldr r1,__KGICAddr"); + asm("ldr r0, [r1, #%a0]" : : "i" ((TInt) (((KIntIdOstMatchMsTimer>>5)<<2)+ _FOFF(GicDistributor, iPendingClear)))); + asm("orr r0,r0,#%a0" : : "i" ((TInt) (0x1<<(KIntIdOstMatchMsTimer&0x1f)))); + asm("str r0, [r1, #%a0]" : : "i" ((TInt) (((KIntIdOstMatchMsTimer>>5)<<2)+ _FOFF(GicDistributor, iPendingClear)))); + __JUMP(,lr); + asm("__KHwTimersBase: "); + asm(".word %a0" : : "i" ((TInt)KHwTimersBase)); + asm("__KGICAddr:"); + asm(".word %a0" : : "i" ((TInt)KHwBaseGlobalIntDist)); + } + + +extern "C" __NAKED__ void __arm_sev() + { + ARM_SEV; + __JUMP(, lr); + } + +#endif // ifdef __SMP__ diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/specific/power.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/specific/power.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,623 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\specific\power.cpp* +*/ + + + +#include "ne1_tb_power.h" + +DNE1_TBPowerController* TNE1_TBPowerController::iPowerController = NULL; + +#ifdef __SMP__ +#ifndef __NO_IDLE_HANDLER_PIL__ +DNE1_SMPIdleHandler* TNE1_TBPowerController::iIdleHandler = NULL; +#endif +const TUint32 DNE1_TBPowerController::KCyclesPerTick = 66666; +const TInt DNE1_TBPowerController::KMaxSleepTicks = TInt(0xffffff00u/DNE1_TBPowerController::KCyclesPerTick)-1; +const TUint32 DNE1_TBPowerController::KWakeUpBeforeTick = 24000; +const TUint32 DNE1_TBPowerController::KTooCloseToTick = 6666; +const TUint32 DNE1_TBPowerController::KMinTimeToTick = 2000; +const TInt DNE1_TBPowerController::KMinIdleTicks = 2; +#if defined(SIMULATE_RETIREMENT) && !defined(__NO_IDLE_HANDLER_PIL__) +volatile TUint32 DNE1_SMPIdleHandler::iRetiredCores = 0; +#endif +#endif // __SMP__ + +inline TUint32 abs_u32diff(TUint32 aA, TUint32 aB) + { + return (aA > aB) ? aA - aB : aB - aA; + } + + +//-/-/-/-/-/-/-/-/-/ class DNE1_SMPIdleHandler /-/-/-/-/-/-/-/-/-/ + +#if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__) + +DNE1_SMPIdleHandler::DNE1_SMPIdleHandler(DNE1_TBPowerController* aController) + :DSMPIdleHandler(),iController(aController) + { + } + +TInt DNE1_SMPIdleHandler::Initialise() + { + TInt r = KErrNone; + DSMPIdleHandler::Initialise(KHwBaseGlobalIntDist,KHwBaseIntIf); +#ifdef SIMULATE_RETIREMENT + // create as many antiIdle threads as there are cored + TInt nc = NKern::NumberOfCpus(); + iIdleStealers = new TDfcQue*[nc]; + __PM_ASSERT_ALWAYS(iIdleStealers); + iIdleStealDfcs = new TDfc*[nc]; + __PM_ASSERT_ALWAYS(iIdleStealDfcs); + for (TInt i = 0; i < nc; i++) + { + TName name = _L("IDLESTEALER"); + name.AppendNum(i); + r = Kern::DfcQCreate(iIdleStealers[i],1,&name); + __PM_ASSERT_ALWAYS(KErrNone==r); + iIdleStealDfcs[i] = new TDfc(IdleSteal,(TAny*) i,iIdleStealers[i],0); + __PM_ASSERT_ALWAYS(iIdleStealDfcs[i]); + NKern::ThreadSetCpuAffinity((NThread*)iIdleStealers[i]->iThread,i); + } + TName name = _L("RETIREENAGE"); + r = Kern::DfcQCreate(iRetireEngageQue,27,&name); +#endif + return r; + } + +TBool DNE1_SMPIdleHandler::DoEnterIdle(TInt aCpuMask, TInt aStage, volatile TAny* /*aU*/) + { + if (aStage & SCpuIdleHandler::EPostamble) + { + iController->IdleTickSuppresionRestore(); + return EFalse; + } +#ifdef SIMULATE_RETIREMENT + // are we retiring? + if (iRetiredCores&aCpuMask) + { + // this should be safe as no cores can be using sync points yet + // as DoEnterIdle is called before all cores are in idle + // and the last core has not arrived yet + // theorically would not return from here + // DoRetireCore would call TIdleSupport::MarkCoreRetired as last + // thing once core is guaranteed not to enter idle handler again + // until it is enaged once more + DoRetireCore(__e32_find_ms1_32(aCpuMask),0); + return EFalse; + } +#endif + return ETrue; + } + + +TBool DNE1_SMPIdleHandler::GetLowPowerMode(TInt aIdleTime, TInt &aLowPowerMode) + { + + aLowPowerMode = 0; + if (aIdleTime < DNE1_TBPowerController::KMinIdleTicks) return EFalse; + iController->IdleTickSuppresionEntry(DNE1_TBPowerController::KWakeUpBeforeTick,aIdleTime); + return ETrue; + } + +TBool DNE1_SMPIdleHandler::EnterLowPowerMode(TInt aMode, TInt aCpuMask, TBool aLastCpu) + { + TIdleSupport::DoWFI(); // maybe we will wake up, or maybe another CPU will wake us up + return ETrue; + } + + +#ifdef SIMULATE_RETIREMENT + +void DNE1_SMPIdleHandler::IdleSteal(TAny* aPtr) + { + TInt cpu = (TInt) aPtr; + PMBTRACE4(KRetireCore,KRetireCoreEntry,cpu); + TUint32 cpuMask = 0x1 << cpu; + + while (cpuMask&iRetiredCores); + PMBTRACE4(KRetireCore,KRetireCoreeXit,cpu); + } + +void DNE1_SMPIdleHandler::DoRetireCore(TInt aCpu, TLinAddr /*aReturnPoint*/) + { + iIdleStealDfcs[aCpu]->RawAdd(); + TIdleSupport::MarkCoreRetired(0x1<Idle(); +#ifndef __SMP__ + iIdleCount++; +#endif + } + +void DNE1_TBPowerController::EnableWakeupEvents() + { + // + // TO DO: (mandatory) + // + // Enable tracking of wake-up events directly in hardware. If the hardware is controlled by a Driver + // or Extension, may need to disable interrupts and preemption around the code that accesses the hardware + // and set up a flag which the Driver/Extension code need to read before modifying the state of that piece + // of hardware. Note in that case the Driver/Extension may need to link to this Library. + // + + // + // EXAMPLE ONLY + // In this example we simply assume that the driver will call the Power Controller every time a + // wakeup event occurr. It is up to the Power Controller to know if it is tracking them or not. + // We also assume that if a wakeup event occurrs when the CPU is in Standby, this will automatically + // bring it back from that state. + iWakeupEventsOn = ETrue; // start tracking wakeup events + } + +void DNE1_TBPowerController::DisableWakeupEvents() + { + // + // TO DO: (mandatory) + // + // Disable tracking of wake-up events directly in hardware or if the hardware is controlled by a Driver or + // Extension need to set up a flag which the Driver/Extension reads whenever the event occurs, in order to + // find out if it needs to deliver notification to the Power Controller + // + iWakeupEventsOn = EFalse; // stop tracking wakeup events + } + +void DNE1_TBPowerController::AbsoluteTimerExpired() + { + if (iTargetState == EPwStandby && iWakeupEventsOn) + { + iWakeupEventsOn = EFalse; // one occurred, no longer track wakeup events + WakeupEvent(); + } + } + +void DNE1_TBPowerController::PowerDown(TTimeK aWakeupST) + { + if (iTargetState == EPwStandby) + { + // + // TO DO: (mandatory) + // + // Converts between the Wakeup time in System Time units as passed in to this function and a Wakeup + // time in RTC units. The following code is given as an example how to convert between System time units + // RTC time units on a system with a 32 bit RTC timer and which is incremented on a second interval: + // + // TUint32 wakeupRTC; + if (aWakeupST) + { + TUint32 nowRTC = TNaviEngine::RtcData(); + TTimeK nowST = Kern::SystemTime(); + __KTRACE_OPT(KPOWER,Kern::Printf("system time: now = 0x%lx(us) wakeup = 0x%lx(us)", nowST, aWakeupST)); + if (aWakeupST < nowST) + return; + Int64 deltaSecs = (aWakeupST - nowST) / 1000000; + if (deltaSecs <= 0) + return; + if (deltaSecs + (Int64)nowRTC > (Int64)(KMaxTInt - 2)) + { + //wakeupRTC = (KMaxTInt - 2); // RTC can't wrap around during standby + __KTRACE_OPT(KPOWER,Kern::Printf("RTC: now = %d(s) wakeup = %d(s)", nowRTC, KMaxTInt - 2)); + } + else + { + //wakeupRTC = nowRTC + deltaSecs; + __KTRACE_OPT(KPOWER,Kern::Printf("RTC: now = %d(s) wakeup = %d(s)", nowRTC, nowRTC + deltaSecs)); + } + } +// else +// wakeupRTC = 0; + // + // TO DO: (optional) + // + // It then uses the calculated value to program the RTC to wakeup the System at the Wakeup + // time ans sets the CPU and remaining hardware to go to the correponding low power mode. When the + // state of the Core and Core Peripherals is not preserved in this mode the following is usually + // required: + // - save current Core state (current Mode, banked registers for each Mode and Stack Pointer for + // both current and User Modes + // - save MMU state: Control Register, TTB and Domain Access Control + // - Flush Dta Cache and drain Write Buffer + // - save Core Peripherals state: Interrupt Controller, Pin Function, Bus State and Clock settings + // SDRAM should be put in self refresh mode. Peripheral devices involved in detection of Wakeup events + // should be left powered. + // The Tick timer should be disabled and the current count of this and other System timers shall be + // saved. + // On wakeing up the state should be restored from the save state as above. SDRAM shall be brought back + // under CPU control, The Tick count shall be restored and timers re-enabled. + + // We assume that if a wakeup event occurrs when the CPU is in Standby, this will automatically + // bring it back from that state. Therefore we stop tracking wakeup events as the Power Manager will + // complete any pending notifications anyway. When the driver delivers its notification, we just ignore + // it. + iWakeupEventsOn = EFalse; // tracking of wakeup events is now done in hardware + } + else + { + Kern::Restart(0x80000000); + } + } + +void DNE1_TBPowerController::IdleTickSuppresionRestore() + { +#ifdef __SMP__ + // only one CPU can enter this function + NETimer& NET = NETimer::Timer(0); + TUint32 timerWrapped = NET.iGTInterrupt&KNETimerGTIInt_TCI; + __e32_io_completion_barrier(); + TUint32 timeIn = NET.iTimerCount; + TUint32 timeSlept = timeIn; + + __PM_ASSERT_DEBUG(NET.iTimerReset == iNextInterrupt); + + if (timerWrapped) + { + // We woke up due to a the main timer. If this is case unless we clear the interrupt + // this result in an extra tick being advanced. We are reprogramming the ISR for a latter + // activation aligned with the correct phase. For timer based wakeups we wake up a bit early + // early enough to allow the time needed to repogram the timer for the next edge + timeSlept+=((iNextInterrupt+KCyclesPerTick)-iOriginalTimerExpire); // timer wrapped if interrupt is pending + ClearTimerInterrupt(); + } + else if (timeIn >= iOriginalTimerExpire) + { + //We woke up after one or more ticks + timeSlept+=(KCyclesPerTick-iOriginalTimerExpire); + } + + TUint32 ticksSlept = timeSlept/KCyclesPerTick; + TUint32 timeToNextInterruptDelta = (ticksSlept+1)*KCyclesPerTick-timeSlept; + + if (timerWrapped==0 && timeIn timeSlept) t1+=timeSlept; + else t1 = timeSlept - remainder; + T1.iTimerCount = t1; + T2.iTimerCount += timeSlept + error; + __e32_io_completion_barrier(); + T1.iTimerCtrl |= KNETimerCtrl_CAE; // start timer 1 first + __e32_io_completion_barrier(); + T2.iTimerCtrl |= KNETimerCtrl_CAE; // start timer 2 + __e32_io_completion_barrier(); + +#ifndef __NO_IDLE_HANDLER_PIL__ + PMBTRACE8(KIdleTickSupression,KTimeSleptTimeNextInt,timeSlept,timeToNextInterrupt); + PMBTRACE8(KIdleTickSupression,KTIcksSlept,ticksSlept,timeToNextInterruptDelta); + PMBTRACE8(KMisc,0x20,timeIn,timerWrapped); +#endif +#endif + } + +void DNE1_TBPowerController::IdleTickSuppresionEntry(TUint32 aWakeDelay, TInt aNextTimer) + { +#ifdef __SMP__ + NETimer& NET = NETimer::Timer(0); + + TUint32 cyclesInTick = NET.iTimerCount; + TUint32 cyclesFullTick= NET.iTimerReset; + __e32_io_completion_barrier(); + + if (abs_u32diff(cyclesFullTick,cyclesInTick) < KTooCloseToTick || (NET.iGTInterrupt&KNETimerGTIInt_TCI)) + return; // to close to edge of tick so we skip this one or even past it + + if (aNextTimer > KMaxSleepTicks) aNextTimer = KMaxSleepTicks; + iNextInterrupt = (aNextTimer)*KCyclesPerTick;//max time we can sleep for + if (iNextInterrupt > (KMaxTUint32-cyclesFullTick)) + return; + // We need to wakeup just before the next timer expire is due + iOriginalTimerExpire=cyclesFullTick;//this is where the current tick would have expired + iNextInterrupt+=(cyclesFullTick -aWakeDelay);//adjust next interrupt time from where we are now + + NET.iTimerReset = iNextInterrupt; + __e32_io_completion_barrier(); + NET.iGTInterrupt = KNETimerGTIInt_All; // clear any pending interrupts + __e32_io_completion_barrier(); +#ifndef __NO_IDLE_HANDLER_PIL__ + PMBTRACE8(KIdleTickSupression,KCyclesInTickCyclesFullTick,cyclesInTick,cyclesFullTick); + PMBTRACE4(KIdleTickSupression,KNextInterrupt,iNextInterrupt); +#endif +//TO DO: Review method of setting iPostambleReuired flag + SCpuIdleHandler* pS = NKern::CpuIdleHandler(); + pS->iPostambleRequired = ETrue; + // stop timers used in NKern::Timestamp, in hardware that will be used for + // product timers of this type would stop when entering low power mode + NETimer& T1 = NETimer::Timer(1); + NETimer& T2 = NETimer::Timer(2); + T2.iTimerCtrl &= ~ KNETimerCtrl_CAE; // clear timer CAE to hold timer value + __e32_io_completion_barrier(); + T1.iTimerCtrl &= ~ KNETimerCtrl_CAE; // stop timer 1 last (lets error increase + __e32_io_completion_barrier(); // but this should be ok as it shouldn't exceed 0xff + iIdleCount++; +#endif + } + +//-/-/-/-/-/-/-/-/-/ class TNE1_TBPowerController /-/-/-/-/-/-/-/-/-/ + + +EXPORT_C void TNE1_TBPowerController::WakeupEvent() + { + if(!iPowerController) + __PM_PANIC("Power Controller not present"); + else if(iPowerController->iWakeupEventsOn) + { + iPowerController->iWakeupEventsOn=EFalse; // one occurred, no longer track wakeup events + iPowerController->WakeupEvent(); + } + } + +// NOTE: these are just enabler functions to simulate core retirement +// they would not stand to any scrutiny as the basis for a proper solution +// they are just here to allow to test the idle handler for robustness against retirement +// whilst we wait for a kernel solution +// @pre thread context, interrupt on, kernel unlocked, no fast mutex held +EXPORT_C void TNE1_TBPowerController::RetireCore(TInt aCpu,TRetireEngageCb& aCb) + { +#if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__) && defined(SIMULATE_RETIREMENT) + SRetireCall* call = new SRetireCall(aCpu,aCb); + if (call && aCpu < NKern::NumberOfCpus()) + { + call->Call(); + } + else + { + + if (!call) aCb.iResult = KErrNoMemory; + else + { + aCb.iResult = KErrArgument; + delete call; + } + aCb.iDfc.Enque(); + } +#endif + } + +// can be called from any core to engage any other core but caller must be outside idle thread +// @pre thread context interrupt on no fast mutex held +EXPORT_C void TNE1_TBPowerController::EngageCore(TInt aCpu, TRetireEngageCb& aCb) + { +#if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__) && defined(SIMULATE_RETIREMENT) + SEngageCall* call = new SEngageCall(aCpu,aCb); + if (call && aCpu < NKern::NumberOfCpus()) + { + call->Call(); + } + else + { + if (!call) aCb.iResult = KErrNoMemory; + else + { + aCb.iResult = KErrArgument; + delete call; + } + aCb.iDfc.Enque(); + } +#endif + } + + +/** + Idle count is incremented everytime ITS takes place + @return idle count +*/ +EXPORT_C TUint TNE1_TBPowerController::IdleCount() + { + return iPowerController->iIdleCount; + } + + +//-/-/-/-/-/-/-/-/-/ class SRetireCall /-/-/-/-/-/-/-/-/-/ + +SRetireCall::SRetireCall(TInt aCpu,TRetireEngageCb& aCb) +#if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__) && defined(SIMULATE_RETIREMENT) + :iTimer(RetireCoreDfcFn,(TAny*)this, + TNE1_TBPowerController::iIdleHandler->iRetireEngageQue,0), + iCpu(aCpu),iCb(aCb),iAllCpusMask(TIdleSupport::AllCpusMask()) +#endif + {}; + +#if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__) && defined(SIMULATE_RETIREMENT) +void SRetireCall::RetireCoreDfcFn(TAny* aParam) + { + + SRetireCall* pC = (SRetireCall*) aParam; + + TUint32 cMask = 0x1<iCpu; + TUint32 toBeRetired = DNE1_SMPIdleHandler::iRetiredCores|cMask; + PMBTRACE4(KRetireCore,0x10,toBeRetired); + if (toBeRetired==pC->iAllCpusMask || (DNE1_SMPIdleHandler::iRetiredCores&cMask) ) + { + //Make sure we don't retire all cores! at least one should run. Core might also already be retired + pC->iCb.iResult = KErrArgument; + pC->iCb.iDfc.Enque(); + delete pC; + return; + } + //Ensure that timer interrupt only hits a cpu that is still active + // this won't be need when core retiring support is complete in the kernel + // as it will migrate all interrupts to remaining enaged cores + // also just for added realism make sure this thread can only run in cores that are still enaged + TUint32 enaged = (~toBeRetired)&pC->iAllCpusMask; + TInt targetCpu = __e32_find_ls1_32(enaged); + TUint32 targetCpuMask = 0x1<iTarget[KIntIdOstMatchMsTimer>>2]&=clear; + __e32_io_completion_barrier(); + GIC->iTarget[KIntIdOstMatchMsTimer>>2]|=targetCpuMask; + __e32_io_completion_barrier(); + NKern::ThreadSetCpuAffinity(NKern::CurrentThread(),targetCpu); + TNE1_TBPowerController::iIdleHandler->ResetSyncPoints(); + DNE1_SMPIdleHandler::iRetiredCores=toBeRetired; + PMBTRACE4(KRetireCore,0x12,DNE1_SMPIdleHandler::iRetiredCores);//,DNE1_TBPowerController::iEngagingCores); + // queue callback + pC->iCb.iResult = KErrNone; + pC->iCb.iDfc.Enque(); + delete pC; + } +#endif + +//-/-/-/-/-/-/-/-/-/ class SEngageCall /-/-/-/-/-/-/-/-/-/ + +SEngageCall::SEngageCall(TInt aCpu,TRetireEngageCb& aCb) +#if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__) && defined(SIMULATE_RETIREMENT) + :iDfc(EngageCoreDfcFn,(TAny*)this, + TNE1_TBPowerController::iIdleHandler->iRetireEngageQue,0),iCpu(aCpu),iCb(aCb) +#endif + {}; + +#if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__) && defined(SIMULATE_RETIREMENT) +void SEngageCall::EngageCoreDfcFn(TAny* aParam) + { + SEngageCall* pC = (SEngageCall*) aParam; + TUint32 cMask = 0x1<iCpu; + PMBTRACE4(KEngageCore,0x10,cMask); + if ((~DNE1_SMPIdleHandler::iRetiredCores)&cMask ) + { + //core is already engaged + pC->iCb.iResult = KErrArgument; + pC->iCb.iDfc.Enque(); + delete pC; + return; + } + + TNE1_TBPowerController::iIdleHandler->ResetSyncPoints(); + TIdleSupport::MarkCoreEngaged(cMask); + DNE1_SMPIdleHandler::iRetiredCores&=~cMask; // This will free calling CPU + PMBTRACE4(KEngageCore,0x11,DNE1_SMPIdleHandler::iRetiredCores); + pC->iCb.iResult = KErrNone; + pC->iCb.iDfc.Enque(); + delete pC; + } +#endif + + + +TInt BinaryPowerInit(); // the Symbian example Battery Monitor and Power HAL handling + +GLDEF_C TInt KernelModuleEntry(TInt aReason) + { + if(aReason==KModuleEntryReasonVariantInit0) + { + // + // + // + __KTRACE_OPT(KPOWER, Kern::Printf("Starting NE1_TBVariant Resource controller")); + return KErrNone; + } + else if(aReason==KModuleEntryReasonExtensionInit0) + { + __KTRACE_OPT(KPOWER, Kern::Printf("Starting NE1_TBVariant power controller")); + // + // TO DO: (optional) + // + // Start the Kernel-side Battery Monitor and hook a Power HAL handling function. + // Symbian provides example code for both of the above in \e32\include\driver\binpower.h + // You may want to write your own versions. + // The call below starts the example Battery Monitor and hooks the example Power HAL handling function + // At the end we return an error to make sure that the entry point is not called again with + // KModuleEntryReasonExtensionInit1 (which would call the constructor of TheResourceManager again) + // + TInt r = BinaryPowerInit(); + if (r!= KErrNone) + __PM_PANIC("Can't initialise Binary Power model"); + DNE1_TBPowerController* c = new DNE1_TBPowerController(); + if(c) + return KErrGeneral; + else + __PM_PANIC("Can't create Power Controller"); + } + else if(aReason==KModuleEntryReasonExtensionInit1) + { + // doesn't get called + } + return KErrArgument; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/specific/powerresources.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/specific/powerresources.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,762 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\specific\powerresources.cpp +* +*/ + + + +#include "resmanpsl.h" +#include + +/** Constructor for board power resource */ +DNE1_TBBoardPowerResource::DNE1_TBBoardPowerResource():DStaticPowerResource(KBoardPower, E_ON) + { + iFlags = 0; //Binary synchronous single user positive sense resource + } + +/** This function updates the resource information for board power resource. Call default implementation to update + generic information about the resource. */ +TInt DNE1_TBBoardPowerResource::GetInfo(TDes8* aInfo)const + { + DStaticPowerResource::GetInfo((TDes8*)aInfo); + TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)aInfo; + buf1->iMinLevel = E_OFF; + buf1->iMaxLevel = E_ON; + return KErrNone; + } + +/** This function takes care of the requested resource operation (read / write) for board power resource. + This is called from PIL on response to change or read resource state. + */ +TInt DNE1_TBBoardPowerResource::DoRequest(TPowerRequest& aRequest) + { + if(aRequest.ReqType() == TPowerRequest::EGet) + { + aRequest.Level() = E_ON; //should be ON + } + else if(aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) + { + //Set to default level + aRequest.Level() = iDefaultLevel; + } + else if(aRequest.ReqType() == TPowerRequest::EChange) + { + //Change to level specified. If the state is OFF then board will be switched off + AsspRegister::Write32(KHwFPGABase+KHoSystemPowerDown, aRequest.Level()); + } + else + { + return KErrNotSupported; + } + return KErrNone; + } + +/** Constructor for display DCLK resource */ +DNE1_TBDisplayDclkResource::DNE1_TBDisplayDclkResource():DStaticPowerResource(KDisplayDclk, EDisplayDclk66500KHz) + { + iFlags = EMultilevel; //Multilevel instantaneous single user positive sense resource + } + +/** This function updates the resource information for display DCLK resource. Call default implementation to + update generic information about the resource. */ +TInt DNE1_TBDisplayDclkResource::GetInfo(TDes8* aInfo)const + { + DStaticPowerResource::GetInfo((TDes8*)aInfo); + TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)aInfo; + buf1->iMinLevel = EDisplayDclk19950KHz; + buf1->iMaxLevel = EDisplayDclk79800KHz; + return KErrNone; + } + +/** This function takes care of the requested resource operation (read /write) for display DCLK. + This is called from PIL on response to change or read resource state. + */ +TInt DNE1_TBDisplayDclkResource::DoRequest(TPowerRequest& aRequest) + { + TInt level; + if(aRequest.ReqType() == TPowerRequest::EGet) + { + level = AsspRegister::Read32(KHwSystemCtrlBase+KHoSCUDisplayDCLKCtrl); + level = ~(level & 0xF); //Need to convert from divider setting to frequency + } + else if(aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) + { + //Set the default level + AsspRegister::Write32(KHwSystemCtrlBase+KHoSCUDisplayDCLKCtrl, ~iDefaultLevel); + aRequest.Level() = iDefaultLevel; + } + else if(aRequest.ReqType() == TPowerRequest::EChange) + { + //Select internal clock + AsspRegister::Write32(KHwSystemCtrlBase+KHoSCUDisplayDCLKCtrl, ~aRequest.Level()); + } + else + { + return KErrNotSupported; + } + return KErrNone; + } + +/** Constructor for LCD power resource */ +DNE1_TBLcdResource::DNE1_TBLcdResource():DStaticPowerResource(KLcdPower, E_ON) + { + iFlags = 0; //Binary instantaneous single user positive sense resource + } + +/** This function updates the resource information for LCD power resource. Call default implementation to + update generic information about the resource. */ +TInt DNE1_TBLcdResource::GetInfo(TDes8* aInfo)const + { + DStaticPowerResource::GetInfo((TDes8*)aInfo); + TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)aInfo; + buf1->iMinLevel = E_OFF; + buf1->iMaxLevel = E_ON; + return KErrNone; + } + +/** This function takes care of the requested resource operation (read / write) for LCD resource. + This is called from PIL on response to change or read resource state. + */ +TInt DNE1_TBLcdResource::DoRequest(TPowerRequest& aRequest) + { + if(aRequest.ReqType() == TPowerRequest::EGet) + { + aRequest.Level() = AsspRegister::Read32(KHwFPGABase+KHoLCDControl) & 0x1; + } + else if(aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) + { + AsspRegister::Modify32(KHwFPGABase+KHoLCDControl, KClearBit0, iDefaultLevel); + aRequest.Level() = iDefaultLevel; + } + else if(aRequest.ReqType() == TPowerRequest::EChange) + { + //Set to requested level + AsspRegister::Modify32(KHwFPGABase+KHoLCDControl, KClearBit0, aRequest.Level()); + } + else + { + return KErrNotSupported; + } + return KErrNone; + } + +/** Constructor for CSI 0 clock resource */ +DNE1_TBCSI0ClockResource::DNE1_TBCSI0ClockResource():DStaticPowerResource(KCSI0Clock, ECSIClkSck1) + { + iFlags = EMultilevel; //Mulitlevel instantaneous single user positive sense resource + } + +/** This function updates the resource information for CSI 0 clock resource. Call default implementation to + update generic information about the resource. + */ +TInt DNE1_TBCSI0ClockResource::GetInfo(TDes8* aInfo)const + { + DStaticPowerResource::GetInfo((TDes8*)aInfo); + TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)aInfo; + buf1->iMinLevel = ECSIClkSck1; + buf1->iMaxLevel = ECSIClk16670KHz; + return KErrNone; + } + +/** This function takes care of the requested resource operation (read /write) for CSI 0 clock resource. + This is called from PIL on response to change or read resource state. + */ +TInt DNE1_TBCSI0ClockResource::DoRequest(TPowerRequest& aRequest) + { + TUint level; + if(aRequest.ReqType() == TPowerRequest::EGet) + { + level = AsspRegister::Read32(KHwBaseCSI0+KHoCSIClockSelect); + aRequest.Level() = ~(level & 0x7); //Convert from divider to frequency + return KErrNone; + } + //Check whether CSIRST is 1, if not return KErrNotsupported + level = AsspRegister::Read32(KHwBaseCSI0+KHoCSIModeControl); + if(level & CSI_UNIT_ENABLE) + { + return KErrNotSupported; + } + //Check whether CSIE is 0 , if not return KErrNotSupported + level = AsspRegister::Read32(KHwBaseCSI0+KHoCSIControl); + if(!(level & CSI_RESET)) + { + return KErrNotSupported; + } + if(aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) + { + //Set to default level + AsspRegister::Modify32(KHwBaseCSI0+KHoCSIClockSelect, KClearBit0_2, ~iDefaultLevel); + aRequest.Level() = iDefaultLevel; + } + else if(aRequest.ReqType() == TPowerRequest::EChange) + { + AsspRegister::Modify32(KHwBaseCSI0+KHoCSIClockSelect, KClearBit0_2, ~aRequest.Level()); + } + else + { + return KErrNotSupported; + } + return KErrNone; + } + +/** Constructor for CSI 1 clock resource */ +DNE1_TBCSI1ClockResource::DNE1_TBCSI1ClockResource():DStaticPowerResource(KCSI1Clock, ECSIClkSck1) + { + iFlags = EMultilevel; //Multilevel instantaneous single user positive sense resource + } + +/** This function updates the resource information for CSI 1 clock resource. Call default implementation to + update generic information about the resource. + */ +TInt DNE1_TBCSI1ClockResource::GetInfo(TDes8* aInfo)const + { + DStaticPowerResource::GetInfo((TDes8*)aInfo); + TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)aInfo; + buf1->iMinLevel = ECSIClkSck1; + buf1->iMaxLevel = ECSIClk16670KHz; + return KErrNone; + } + +/** This function takes care of the requested resource operation (read/write) for CSI 1 clock resource. + This is called from PIL on response to change or read resource state. + */ +TInt DNE1_TBCSI1ClockResource::DoRequest(TPowerRequest& aRequest) + { + TUint level; + if(aRequest.ReqType() == TPowerRequest::EGet) + { + level = AsspRegister::Read32(KHwBaseCSI1+KHoCSIClockSelect); + level = ~(level & 0x7); + return KErrNone; + } + //Check whether CSIRST is 1, if not return KErrNotsupported + level = AsspRegister::Read32(KHwBaseCSI1+KHoCSIModeControl); + if(level & CSI_UNIT_ENABLE) + { + return KErrNotSupported; + } + //Check whether CSIE is 0 , if not return KErrNotSupported + level = AsspRegister::Read32(KHwBaseCSI1+KHoCSIControl); + if(!(level & CSI_RESET)) + { + return KErrNotSupported; + } + if(aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) + { + //Set to default level + AsspRegister::Modify32(KHwBaseCSI1+KHoCSIClockSelect, KClearBit0_2, ~iDefaultLevel); + aRequest.Level() = iDefaultLevel; + } + else if(aRequest.ReqType() == TPowerRequest::EChange) + { + //Change the resource to the requested level + AsspRegister::Modify32(KHwBaseCSI1+KHoCSIClockSelect, KClearBit0_2, ~aRequest.Level()); + } + else + { + return KErrNotSupported; + } + return KErrNone; + } + +/** Constructor for I2S 0 MCLK divider resource */ +DNE1_TBI2S0MclkResource::DNE1_TBI2S0MclkResource():DStaticPowerResource(KI2S0Mclk, EI2SMclk36864KHz) + { + //This resource also takes care of masking the DCLK clock and therefore classified as multiproperty + iFlags = EMultiProperty; + } + +/** This function updates the resource information for I2S 0 clock resource. Call default implementation to + update generic information about the resource + */ +TInt DNE1_TBI2S0MclkResource::GetInfo(TDes8* aInfo)const + { + DStaticPowerResource::GetInfo((TDes8*)aInfo); + TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)aInfo; + buf1->iMinLevel = EI2SMclkMask; + buf1->iMaxLevel = EI2SMclk16934KHz; + return KErrNone; + } + +/** This function takes care of the requested resource operation (read / write) for I2S 0 MCLK resource. + This is called from PIL on response to change or read resource state. + */ +TInt DNE1_TBI2S0MclkResource::DoRequest(TPowerRequest& aRequest) + { + if(aRequest.ReqType() == TPowerRequest::EGet) + { + aRequest.Level() = AsspRegister::Read32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl) & 0xF; + } + else if(aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) + { + //Set to default level + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl, KClearBit0_3, iDefaultLevel); + aRequest.Level() = iDefaultLevel; + } + else if(aRequest.ReqType() == TPowerRequest::EChange) + { + if(aRequest.Level() == EI2SMclkMask) //Enable DCLK Mask + { + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUClockMaskCtrl, KClearBit18, KSetBit18); + } + else + { + //Set the request frequency + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl, KClearBit0_3, aRequest.Level()); + //Disable the clock mask + TUint level = AsspRegister::Read32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl); + if(!(level & KSetBit18)) + { + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl, KClearBit18, KClearBit18); + } + } + } + else + { + return KErrNotSupported; + } + return KErrNone; + } + +/** Constructor for I2S 1 MCLK divider resource */ +DNE1_TBI2S1MclkResource::DNE1_TBI2S1MclkResource():DStaticPowerResource(KI2S1Mclk, EI2SMclk36864KHz) + { + iFlags = EMultiProperty; + } + +/** This function updates the resource information for I2S 1 clock resource. Call default implementation to + update generic information about the resource + */ +TInt DNE1_TBI2S1MclkResource::GetInfo(TDes8* aInfo)const + { + DStaticPowerResource::GetInfo((TDes8*)aInfo); + TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)aInfo; + buf1->iMinLevel = EI2SMclkMask; + buf1->iMaxLevel = EI2SMclk16934KHz; + return KErrNone; + } + +/** This function takes care of the requested resource operation (read / write) for I2S 1 MCLK clock resource. + This is called from PIL on response to change or read resource state. + */ +TInt DNE1_TBI2S1MclkResource::DoRequest(TPowerRequest& aRequest) + { + TUint level; + if(aRequest.ReqType() == TPowerRequest::EGet) + { + level = AsspRegister::Read32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl); + aRequest.Level() = (level >> SHIFT_BY_8) & 0xF; + } + else if(aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) + { + //Set to default level + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl, KClearBit8_11, (iDefaultLevel << SHIFT_BY_8)); + aRequest.Level() = iDefaultLevel; + } + else if(aRequest.ReqType() == TPowerRequest::EChange) + { + if(aRequest.Level() == EI2SMclkMask) //Enable DCLK Mask + { + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUClockMaskCtrl, KClearBit19, KSetBit19); + } + else + { + //Set the request frequency + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl, KClearBit8_11, (aRequest.Level() << SHIFT_BY_8)); + //Disable the clock mask + level = AsspRegister::Read32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl); + if(!(level & KSetBit19)) + { + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl, KClearBit19, KClearBit19); + } + } + } + else + { + return KErrNotSupported; + } + return KErrNone; + } + +/** Constructor for I2S 2 MCLK divider resource */ +DNE1_TBI2S2MclkResource::DNE1_TBI2S2MclkResource():DStaticPowerResource(KI2S2Mclk, EI2SMclk36864KHz) + { + iFlags = EMultiProperty; + } + +/** This function updates the resource information for I2S 2 MCLK clock resource. Call default implementation to + update generic information about the resource + */ +TInt DNE1_TBI2S2MclkResource::GetInfo(TDes8* aInfo)const + { + DStaticPowerResource::GetInfo((TDes8*)aInfo); + TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)aInfo; + buf1->iMinLevel = EI2SMclkMask; + buf1->iMaxLevel = EI2SMclk16934KHz; + return KErrNone; + } + +/** This function takes care of the requested resource operation (read / write) for I2S 2 MCLK clock resource. + This is called from PIL on response to change or read resource state. + */ +TInt DNE1_TBI2S2MclkResource::DoRequest(TPowerRequest& aRequest) + { + TUint level; + if(aRequest.ReqType() == TPowerRequest::EGet) + { + level = AsspRegister::Read32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl); + aRequest.Level() = (level >> SHIFT_BY_16) & 0xF; + } + else if(aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) + { + //Set to default level + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl, KClearBit16_19, (iDefaultLevel << SHIFT_BY_16)); + aRequest.Level() = iDefaultLevel; + } + else if(aRequest.ReqType() == TPowerRequest::EChange) + { + if(aRequest.Level() == EI2SMclkMask) //Enable DCLK Mask + { + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUClockMaskCtrl, KClearBit20, KSetBit20); + } + else + { + //Set the request frequency + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl, KClearBit16_19, + (aRequest.Level() << SHIFT_BY_16)); + //Disable the clock mask + level = AsspRegister::Read32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl); + if(!(level & KSetBit20)) + { + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl, KClearBit20, KClearBit20); + } + } + } + else + { + return KErrNotSupported; + } + return KErrNone; + } + +/** Constructor for I2S 3 MCLK divider resource */ +DNE1_TBI2S3MclkResource::DNE1_TBI2S3MclkResource():DStaticPowerResource(KI2S3Mclk, EI2SMclk36864KHz) + { + iFlags = EMultiProperty; + } + +/** This function updates the resource information for I2S 3 MCLK clock resource. Call default implementation to + update generic information about the resource + */ +TInt DNE1_TBI2S3MclkResource::GetInfo(TDes8* aInfo)const + { + DStaticPowerResource::GetInfo((TDes8*)aInfo); + TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)aInfo; + buf1->iMinLevel = EI2SMclkMask; + buf1->iMaxLevel = EI2SMclk16934KHz; + return KErrNone; + } + +/** This function takes care of the requested resource operation (read / write) for I2S 3 MCLK clock resource. + This is called from PIL on response to change or read resource state. + */ +TInt DNE1_TBI2S3MclkResource::DoRequest(TPowerRequest& aRequest) + { + TUint level; + if(aRequest.ReqType() == TPowerRequest::EGet) + { + level = AsspRegister::Read32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl); + aRequest.Level() = (level >> SHIFT_BY_24) & 0xF; + } + else if(aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) + { + //Set to default level + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl, KClearBit24_27, (iDefaultLevel << SHIFT_BY_24)); + aRequest.Level() = iDefaultLevel; + } + else if(aRequest.ReqType() == TPowerRequest::EChange) + { + if(aRequest.Level() == EI2SMclkMask) //Enable DCLK Mask + { + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUClockMaskCtrl, KClearBit21, KSetBit21); + } + else + { + //Set the request frequency + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl, KClearBit24_27, + (aRequest.Level() << SHIFT_BY_24)); + //Disable the clock mask + level = AsspRegister::Read32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl); + if(!(level & KSetBit21)) + { + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl, KClearBit21, KClearBit21); + } + } + } + else + { + return KErrNotSupported; + } + return KErrNone; + } + +/** Constructor for I2S 0 SCLK resource */ +DNE1_TBI2S0SclkResource::DNE1_TBI2S0SclkResource():DStaticPowerResource(KI2S0Sclk, EI2SSclk8000Hz) + { + iFlags = EMultilevel; + } + +/** This function updates the resource information for I2S 0 SCLK clock resource. Call default implementation to + update generic information about the resource + */ +TInt DNE1_TBI2S0SclkResource::GetInfo(TDes8* aInfo)const + { + DStaticPowerResource::GetInfo((TDes8*)aInfo); + TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)aInfo; + buf1->iMinLevel = EI2SSclk8000Hz; + buf1->iMaxLevel = EI2SSclk44100Hz; + return KErrNone; + } + +/** This function takes care of the requested resource operation (read / write) for I2S 0 SCLK clock resource. + This is called from PIL on response to change or read resource state. + */ +TInt DNE1_TBI2S0SclkResource::DoRequest(TPowerRequest& aRequest) + { + TUint level; + if(aRequest.ReqType() == TPowerRequest::EGet) + { + level = AsspRegister::Read32(KHwBaseI2S0+KHoI2SCtrl); + aRequest.Level() = (level >> SHIFT_BY_16) & 0xF; + } + else if(aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) + { + //Set to default level + AsspRegister::Modify32(KHwBaseI2S0+KHoI2SCtrl, KClearBit16_19, (iDefaultLevel << SHIFT_BY_16)); + aRequest.Level() = iDefaultLevel; + } + else if(aRequest.ReqType() == TPowerRequest::EChange) + { + //Set to request frequency + AsspRegister::Modify32(KHwBaseI2S0+KHoI2SCtrl, KClearBit16_19, (aRequest.Level() << SHIFT_BY_16)); + } + else + { + return KErrNotSupported; + } + return KErrNone; + } + +/** Constructor for I2S 1 SCLK resource */ +DNE1_TBI2S1SclkResource::DNE1_TBI2S1SclkResource():DStaticPowerResource(KI2S1Sclk, EI2SSclk8000Hz) + { + iFlags = EMultilevel; + } + +/** This function updates the resource information for I2S 1 SCLK clock resource. Call default implementation to + update generic information about the resource + */ +TInt DNE1_TBI2S1SclkResource::GetInfo(TDes8* aInfo)const + { + DStaticPowerResource::GetInfo((TDes8*)aInfo); + TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)aInfo; + buf1->iMinLevel = EI2SSclk8000Hz; + buf1->iMaxLevel = EI2SSclk44100Hz; + return KErrNone; + } + +/** This function takes care of the requested resource operation (read / write) for I2S 1 SCLK clock resource. + This is called from PIL on response to change or read resource state. + */ +TInt DNE1_TBI2S1SclkResource::DoRequest(TPowerRequest& aRequest) + { + TUint level; + if(aRequest.ReqType() == TPowerRequest::EGet) + { + level = AsspRegister::Read32(KHwBaseI2S1+KHoI2SCtrl); + aRequest.Level() = (level >> SHIFT_BY_16) & 0xF; + } + else if(aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) + { + //Set to default level + AsspRegister::Modify32(KHwBaseI2S1+KHoI2SCtrl, KClearBit16_19, (iDefaultLevel << SHIFT_BY_16)); + aRequest.Level() = iDefaultLevel; + } + else if(aRequest.ReqType() == TPowerRequest::EChange) + { + //Set to request frequency + AsspRegister::Modify32(KHwBaseI2S1+KHoI2SCtrl, KClearBit16_19, (aRequest.Level() << SHIFT_BY_16)); + } + else + { + return KErrNotSupported; + } + return KErrNone; + } + +/** Constructor for I2S 2 SCLK resource */ +DNE1_TBI2S2SclkResource::DNE1_TBI2S2SclkResource():DStaticPowerResource(KI2S2Sclk, EI2SSclk8000Hz) + { + iFlags = EMultilevel; + } + +/** This function updates the resource information for I2S 2 SCLK clock resource. Call default implementation to + update generic information about the resource + */ +TInt DNE1_TBI2S2SclkResource::GetInfo(TDes8* aInfo)const + { + DStaticPowerResource::GetInfo((TDes8*)aInfo); + TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)aInfo; + buf1->iMinLevel = EI2SSclk8000Hz; + buf1->iMaxLevel = EI2SSclk44100Hz; + return KErrNone; + } + +/** This function takes care of the requested resource operation (read / write) for I2S 2 SCLK clock resource. + This is called from PIL on response to change or read resource state. + */ +TInt DNE1_TBI2S2SclkResource::DoRequest(TPowerRequest& aRequest) + { + TUint level; + if(aRequest.ReqType() == TPowerRequest::EGet) + { + level = AsspRegister::Read32(KHwBaseI2S2+KHoI2SCtrl); + aRequest.Level() = (level >> SHIFT_BY_16) & 0xF; + } + else if(aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) + { + //Set to default level + AsspRegister::Modify32(KHwBaseI2S2+KHoI2SCtrl, KClearBit16_19, (iDefaultLevel << SHIFT_BY_16)); + aRequest.Level() = iDefaultLevel; + } + else if(aRequest.ReqType() == TPowerRequest::EChange) + { + //Set to request frequency + AsspRegister::Modify32(KHwBaseI2S2+KHoI2SCtrl, KClearBit16_19, (aRequest.Level() << SHIFT_BY_16)); + } + else + { + return KErrNotSupported; + } + return KErrNone; + } + +/** Constructor for I2S 3 SCLK resource */ +DNE1_TBI2S3SclkResource::DNE1_TBI2S3SclkResource():DStaticPowerResource(KI2S3Sclk, EI2SSclk8000Hz) + { + iFlags = EMultilevel; + } + +/** This function updates the resource information for I2S 3 SCLK clock resource. Call default implementation to + update generic information about the resource + */ +TInt DNE1_TBI2S3SclkResource::GetInfo(TDes8* aInfo)const + { + DStaticPowerResource::GetInfo((TDes8*)aInfo); + TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)aInfo; + buf1->iMinLevel = EI2SSclk8000Hz; + buf1->iMaxLevel = EI2SSclk44100Hz; + return KErrNone; + } + +/** This function takes care of the requested resource operation (read / write) for I2S 3 SCLK clock resource. + This is called from PIL on response to change or read resource state. + */ +TInt DNE1_TBI2S3SclkResource::DoRequest(TPowerRequest& aRequest) + { + TUint level; + if(aRequest.ReqType() == TPowerRequest::EGet) + { + level = AsspRegister::Read32(KHwBaseI2S3+KHoI2SCtrl); + aRequest.Level() = (level >> SHIFT_BY_16) & 0xF; + } + else if(aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) + { + //Set to default level + AsspRegister::Modify32(KHwBaseI2S3+KHoI2SCtrl, KClearBit16_19, (iDefaultLevel << SHIFT_BY_16)); + aRequest.Level() = iDefaultLevel; + } + else if(aRequest.ReqType() == TPowerRequest::EChange) + { + //Set to request frequency + AsspRegister::Modify32(KHwBaseI2S3+KHoI2SCtrl, KClearBit16_19, (aRequest.Level() << SHIFT_BY_16)); + } + else + { + return KErrNotSupported; + } + return KErrNone; + } + +/** Constructor for PCI Clock resource */ +DNE1_TBPCIClockResource::DNE1_TBPCIClockResource():DStaticPowerResource(KPCIClk, E_OFF) + { + iFlags = 0; + } + +/** This function updates the resource information for PCI mask clock resource. Call default implementation to + update generic information about the resource + */ +TInt DNE1_TBPCIClockResource::GetInfo(TDes8* aInfo)const + { + DStaticPowerResource::GetInfo((TDes8*)aInfo); + TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*)aInfo; + buf1->iMinLevel = E_OFF; + buf1->iMaxLevel = E_ON; + return KErrNone; + } + +/** This function takes care of the requested resource operation (read / write) for PCI clock resource. + This is called from PIL on response to change or read resource state. + */ +TInt DNE1_TBPCIClockResource::DoRequest(TPowerRequest& aRequest) + { + TUint level; + if(aRequest.ReqType() == TPowerRequest::EGet) + { + level = AsspRegister::Read32(KHwSystemCtrlBase+KHoSCUClockMaskCtrl); + aRequest.Level() = (level >> SHIFT_BY_9) & 0x1; + } + else if(aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) + { + //Set to default level + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl, KClearBit09, KSetBit09); + aRequest.Level() = iDefaultLevel; + } + else if(aRequest.ReqType() == TPowerRequest::EChange) + { + if(aRequest.Level() == E_OFF) + {//Mask the clock + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUClockMaskCtrl, KClearBit09, KSetBit09); + } + else + {//Enable the clock + AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUClockMaskCtrl, KClearBit09, KClearBit09); + } + } + else + { + return KErrNotSupported; + } + return KErrNone; + } + + + + + + + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/specific/resmanpsl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/specific/resmanpsl.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,125 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\specific\resmanpsl.cpp +* +*/ + + + +#include "resmanpsl.h" + +static DNE1_TBPowerResourceController TheController; +/** Entry point of resource controller */ +DECLARE_RESOURCE_MANAGER_EXTENSION(TheController) + { + __KTRACE_OPT(KBOOT, Kern::Printf("CreateController called")); + new(&TheController) DNE1_TBPowerResourceController; + return; + } + +/** Constructor */ +DNE1_TBPowerResourceController::DNE1_TBPowerResourceController() : DPowerResourceController() + { + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DNE1_TBPowerResourceController Called\n")); + } + +/** This function is called by PIL during its creation phase. + It creates a DFC queue and then invokes setDfcQ function of PIL to set the queue. + It also initialises the pools with appropriate size. + */ +TInt DNE1_TBPowerResourceController::DoInitController() + { + TInt r = KErrNone; + __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DNE1_TBPowerResourceController::DoInitController()")); + //Create a DFC queue + r = Kern::DfcQCreate(iDfcQ, KDfcQThreadPriority, &KResmanName); + if(r != KErrNone) + { + Kern::Printf("DFC Queue creation failed"); + return r; + } + +#ifdef CPU_AFFINITY_ANY + NKern::ThreadSetCpuAffinity((NThread*)(iDfcQ->iThread), KCpuAffinityAny); +#endif + + //Call the resource controller to set the DFCQ + SetDfcQ(iDfcQ); + //Init pools + r = InitPools(KERNEL_CLIENTS, USER_CLIENTS, CLIENT_LEVELS, REQUESTS); + return r; + } + +/** This function is called by PIL to register the static resources. + It creates an array to hold the static resource and also creates the resources and updates + in the array. + */ +TInt DNE1_TBPowerResourceController::DoRegisterStaticResources(DStaticPowerResource**& aStaticResourceArray, + TUint16& aStaticResourceCount) + { + __KTRACE_OPT(KRESMANAGER, Kern::Printf("DNE1_TBPowerResourceController::DoRegisterStaticResources")); + /** Create the static resource array */ + aStaticResourceArray = (DStaticPowerResource**)new(DStaticPowerResource*[EMaxResourceCount]); + if(!aStaticResourceArray) + return KErrNoMemory; + + DStaticPowerResource* pR = NULL; + + /** Create I2S0 MCLK resource and add to the static resource array */ + REGISTER_RESOURCE(DNE1_TBI2S0MclkResource, aStaticResourceArray, aStaticResourceCount); + + /** Create I2S1 MCLK resource and add to the static resource array */ + REGISTER_RESOURCE(DNE1_TBI2S1MclkResource, aStaticResourceArray, aStaticResourceCount); + + /** Create I2S2 MCLK resource and add to the static resource array */ + REGISTER_RESOURCE(DNE1_TBI2S2MclkResource, aStaticResourceArray, aStaticResourceCount); + + /** Create I2S3 MCLK resource and add to the static resource array */ + REGISTER_RESOURCE(DNE1_TBI2S3MclkResource, aStaticResourceArray, aStaticResourceCount); + + /** Create I2S0 SCLK resource and add to the static resource array */ + REGISTER_RESOURCE(DNE1_TBI2S0SclkResource, aStaticResourceArray, aStaticResourceCount); + + /** Create I2S1 SCLK resource and add to the static resource array */ + REGISTER_RESOURCE(DNE1_TBI2S1SclkResource, aStaticResourceArray, aStaticResourceCount); + + /** Create I2S2 SCLK resource and add to the static resource array */ + REGISTER_RESOURCE(DNE1_TBI2S2SclkResource, aStaticResourceArray, aStaticResourceCount); + + /** Create I2S3 SCLK resource and add to the static resource array */ + REGISTER_RESOURCE(DNE1_TBI2S3SclkResource, aStaticResourceArray, aStaticResourceCount); + + /** Create CSI0 clock resource and add to the static resource array */ + REGISTER_RESOURCE(DNE1_TBCSI0ClockResource, aStaticResourceArray, aStaticResourceCount); + + /** Create CSI1 clock resource and add to the static resource array */ + REGISTER_RESOURCE(DNE1_TBCSI1ClockResource, aStaticResourceArray, aStaticResourceCount); + + /** Create Display DCLK resource and add to the static resource array */ + REGISTER_RESOURCE(DNE1_TBDisplayDclkResource, aStaticResourceArray, aStaticResourceCount); + + /** Create LCD resource and add to the static resource array */ + REGISTER_RESOURCE(DNE1_TBLcdResource, aStaticResourceArray, aStaticResourceCount); + + /** Create Board Power resource and add to the static resource array */ + REGISTER_RESOURCE(DNE1_TBBoardPowerResource, aStaticResourceArray, aStaticResourceCount); + + /** Create PCI clock mask enable resource and add to the static resource array */ + REGISTER_RESOURCE(DNE1_TBPCIClockResource, aStaticResourceArray, aStaticResourceCount); + + return KErrNone; + } + + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/specific/variant.cia --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/specific/variant.cia Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,245 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\specific\variant.cia +* +*/ + + + +#include +#include "variant.h" +#include "mconf.h" + +/****************************************************************************** + * Interrupt handling/dispatch + ******************************************************************************/ +__NAKED__ void XIntDispatch(TAny*) + { + // Service second-level Variant Interrupts + // Enter with r0->{Variant int controller base; Handlers;} + asm("stmfd sp!, {r4,lr} "); + asm("ldmia r0, {r3,r4} "); // r3=Variant interrupt controller base, r4->handlers + asm("0: "); + asm("ldr r0, [r3, #%a0]" : : "i" ((TInt)KHoIntContEnable)); // r0=bitmask with enabled interrupts + asm("ldr r1, [r3, #%a0]" : : "i" ((TInt)KHoIntContPending)); // r1=bitmask with pending interrupts + asm("mov r2, #31 "); // int id + asm("and r0, r0, r1 "); + asm("bics r0, r0, #0xf8000000 "); // mask unused bits (only 26 2nd-level ints defined) + asm("ldmeqfd sp!, {r4,pc} "); // if no 2nd level interrupts pending, exit + asm("cmp r0, #0x00010000 "); + asm("movcc r0, r0, lsl #16 "); + asm("subcc r2, r2, #16 "); + asm("cmp r0, #0x01000000 "); + asm("movcc r0, r0, lsl #8 "); + asm("subcc r2, r2, #8 "); + asm("cmp r0, #0x10000000 "); + asm("movcc r0, r0, lsl #4 "); + asm("subcc r2, r2, #4 "); + asm("cmp r0, #0x40000000 "); + asm("movcc r0, r0, lsl #2 "); + asm("subcc r2, r2, #2 "); + asm("cmp r0, #0x80000000 "); + asm("subcc r2, r2, #1 "); // r2=bit no. of MS 1 + asm("add r0, r4, r2, lsl #3 "); // r0->handler for this interrupt + asm("adr lr, 0b "); // look again after calling handler + asm("ldmia r0, {r0,pc} "); // jump to handler + } + + +extern "C" __NAKED__ void __arm_sev() + { + ARM_SEV; + __JUMP(, lr); + } + +__NAKED__ void __cpu_idle() + { + __DATA_SYNC_BARRIER_Z__(r1); + ARM_WFI; + __JUMP(,lr); + } + +#ifdef __SMP__ +__NAKED__ void __cache_off() + { + asm("stmfd sp!, {r4-r12,lr} "); + asm("ldr r7, __SCUAddr "); + asm("mov r8, #0 "); + __ASM_CLI(); + asm("bl cinvd "); // Clean and invalidate D cache + asm("mrc p15, 0, r0, c1, c0, 1 "); // get AUXCR + asm("bic r0, r0, #0x20 "); // clear SMP bit + asm("mcr p15, 0, r0, c1, c0, 1 "); + asm("mcr p15, 0, r8, c7, c10, 4 "); // DSB + asm("mcr p15, 0, r8, c7, c5, 4 "); // ISB + asm("mrc p15, 0, r2, c0, c0, 5 "); // CPU number + asm("mov r2, r2, lsl #2 "); // *4 + asm("mov r3, #15 "); + asm("mov r3, r3, lsl r2 "); // r3 = 0x0f << (4*cpu#) + asm("str r3, [r7, #0x0C] "); // Invalidate SCU tags for this CPU + + asm("mcr p15, 0, r8, c7, c10, 4 "); // DSB + asm("mcr p15, 0, r8, c7, c5, 4 "); // ISB + asm("mrc p15, 0, r0, c1, c0, 0 "); // get SCTLR + asm("bic r0, r0, #0x04 "); // disable D cache + asm("mcr p15, 0, r0, c1, c0, 0 "); + asm("mcr p15, 0, r8, c7, c10, 4 "); // DSB + asm("mcr p15, 0, r8, c7, c5, 4 "); // ISB + asm("bl invd "); // Invalidate D cache + + asm("mrc p15, 0, r2, c0, c0, 5 "); // CPU number + asm("mov r2, r2, lsl #1 "); // *2 + asm("mov r3, #3 "); + asm("mov r3, r3, lsl r2 "); // r3 = 0x03 << (2*cpu#) + asm("ldr r1, [r7, #0x08] "); // SCU CPU status register + asm("orr r1, r1, r3 "); // set bits to 11 (power off mode) + asm("str r1, [r7, #0x08] "); + asm("mcr p15, 0, r8, c7, c10, 4 "); // DSB + + asm("ldmfd sp!, {r4-r12,pc} "); + + asm("__SCUAddr: "); + asm(".word %a0" : : "i" ((TInt)KHwBaseSCU)); + + + // Clean and invalidate the D cache + // this code assumes number of sets is a multiple of 4 + // modifies r0-r6,r12 + asm("cinvd: "); + asm("mrc p15, 0, r0, c0, c0, 1 "); // r0 = cache type register + asm("mov r4, r0, lsr #12 "); + asm("mov r5, r0, lsr #15 "); + asm("mov r6, r0, lsr #18 "); + asm("and r4, r4, #3 "); // r4 = Dsize.len + asm("and r5, r5, #7 "); // r5 = Dsize.assoc + asm("and r6, r6, #15 "); // r6 = Dsize.size + asm("mov r2, #8 "); + asm("mov r2, r2, lsl r4 "); // r2 = D cache line length + asm("add r1, r6, #6 "); // r1 = Dsize.size + 6 = log2(size/8 bytes) + asm("sub r1, r1, r4 "); // r1 = log2(size/line length) + asm("mov r3, #1 "); + asm("mov r3, r3, lsl r1 "); // r3 = size in lines if M=0 + asm("add r1, r6, #9 "); // r1 = Dsize.size + 9 = log2(size bytes) + asm("sub r1, r1, r5 "); // r1 = log2(size/assoc) + asm("mov r12, #1 "); + asm("mov r1, r12, lsl r1 "); // r1 = way size + asm("mov r12, r12, ror r5 "); // r12 = 2^32>>floor(log2(assoc)) + asm("and r12, r12, #0xFF000000 "); // lose bit 0 if assoc=1 + asm("tst r0, #0x4000 "); // test Dsize.M + asm("addne r3, r3, r3, lsr #1 "); // multiply size by 1.5 if M=1 + asm("movne r12, r12, lsr #1 "); // 1 more bit for WAY field if M=1 + + // Have r2 = line length/bytes, r3 = cache size/lines + // r1 = size/assoc (=way size) + // r12 = iCleanAndInvalidatePtr=2^32 >> ceil(log2(assoc)) + + asm("mov r0, #0 "); // cache index + asm("1: "); + asm("mcr p15, 0, r0, c7, c14, 2 "); // CleanAndInvalidate line whose way/set index is in r0 + asm("add r0, r0, r2 "); // next line in way + asm("mcr p15, 0, r0, c7, c14, 2 "); // CleanAndInvalidate line whose way/set index is in r0 + asm("add r0, r0, r2 "); // next line in way + asm("mcr p15, 0, r0, c7, c14, 2 "); // CleanAndInvalidate line whose way/set index is in r0 + asm("add r0, r0, r2 "); // next line in way + asm("mcr p15, 0, r0, c7, c14, 2 "); // CleanAndInvalidate line whose way/set index is in r0 + asm("add r0, r0, r2 "); // next line in way + asm("tst r0, r1 "); // all lines in way done? + asm("bic r0, r0, r1 "); // clear set index + asm("addne r0, r0, r12 "); // if all lines in way done, next way + asm("subs r3, r3, #4 "); // 4 lines done + asm("bne 1b "); // loop through lines + asm("mcr p15, 0, r8, c7, c10, 4 "); // DSB + __JUMP(, lr); + + // Invalidate the D cache + // this code assumes number of sets is a multiple of 4 + // modifies r0-r6,r12 + asm("invd: "); + asm("mrc p15, 0, r0, c0, c0, 1 "); // r0 = cache type register + asm("mov r4, r0, lsr #12 "); + asm("mov r5, r0, lsr #15 "); + asm("mov r6, r0, lsr #18 "); + asm("and r4, r4, #3 "); // r4 = Dsize.len + asm("and r5, r5, #7 "); // r5 = Dsize.assoc + asm("and r6, r6, #15 "); // r6 = Dsize.size + asm("mov r2, #8 "); + asm("mov r2, r2, lsl r4 "); // r2 = D cache line length + asm("add r1, r6, #6 "); // r1 = Dsize.size + 6 = log2(size/8 bytes) + asm("sub r1, r1, r4 "); // r1 = log2(size/line length) + asm("mov r3, #1 "); + asm("mov r3, r3, lsl r1 "); // r3 = size in lines if M=0 + asm("add r1, r6, #9 "); // r1 = Dsize.size + 9 = log2(size bytes) + asm("sub r1, r1, r5 "); // r1 = log2(size/assoc) + asm("mov r12, #1 "); + asm("mov r1, r12, lsl r1 "); // r1 = way size + asm("mov r12, r12, ror r5 "); // r12 = 2^32>>floor(log2(assoc)) + asm("and r12, r12, #0xFF000000 "); // lose bit 0 if assoc=1 + asm("tst r0, #0x4000 "); // test Dsize.M + asm("addne r3, r3, r3, lsr #1 "); // multiply size by 1.5 if M=1 + asm("movne r12, r12, lsr #1 "); // 1 more bit for WAY field if M=1 + + // Have r2 = line length/bytes, r3 = cache size/lines + // r1 = size/assoc (=way size) + // r12 = iCleanAndInvalidatePtr=2^32 >> ceil(log2(assoc)) + + asm("mov r0, #0 "); // cache index + asm("1: "); + asm("mcr p15, 0, r0, c7, c6, 2 "); // Invalidate line whose way/set index is in r0 + asm("add r0, r0, r2 "); // next line in way + asm("mcr p15, 0, r0, c7, c6, 2 "); // Invalidate line whose way/set index is in r0 + asm("add r0, r0, r2 "); // next line in way + asm("mcr p15, 0, r0, c7, c6, 2 "); // Invalidate line whose way/set index is in r0 + asm("add r0, r0, r2 "); // next line in way + asm("mcr p15, 0, r0, c7, c6, 2 "); // Invalidate line whose way/set index is in r0 + asm("add r0, r0, r2 "); // next line in way + asm("tst r0, r1 "); // all lines in way done? + asm("bic r0, r0, r1 "); // clear set index + asm("addne r0, r0, r12 "); // if all lines in way done, next way + asm("subs r3, r3, #4 "); // 4 lines done + asm("bne 1b "); // loop through lines + asm("mcr p15, 0, r8, c7, c10, 4 "); // DSB + __JUMP(, lr); + } + +__NAKED__ void __cache_on() + { + asm("stmfd sp!, {r4-r12,lr} "); + asm("mov r8, #0 "); + asm("mcr p15, 0, r8, c7, c10, 4 "); // DSB + asm("ldr r7, __SCUAddr "); + asm("mrc p15, 0, r2, c0, c0, 5 "); // CPU number + asm("mov r2, r2, lsl #1 "); // *2 + asm("mov r3, #3 "); + asm("mov r3, r3, lsl r2 "); // r3 = 0x03 << (2*cpu#) + asm("ldr r1, [r7, #0x08] "); // SCU CPU status register + asm("bic r1, r1, r3 "); // set bits to 00 (normal mode) + asm("str r1, [r7, #0x08] "); + asm("mcr p15, 0, r8, c7, c10, 4 "); // DSB + asm("bl cinvd "); // Clean and invalidate D cache + asm("mcr p15, 0, r8, c7, c10, 4 "); // DSB + asm("mcr p15, 0, r8, c7, c5, 4 "); // ISB + asm("mrc p15, 0, r0, c1, c0, 0 "); // get SCTLR + asm("orr r0, r0, #0x04 "); // enable D cache + asm("mcr p15, 0, r0, c1, c0, 0 "); + asm("mcr p15, 0, r8, c7, c10, 4 "); // DSB + asm("mcr p15, 0, r8, c7, c5, 4 "); // ISB + asm("mrc p15, 0, r0, c1, c0, 1 "); // get AUXCR + asm("orr r0, r0, #0x20 "); // set SMP bit + asm("mcr p15, 0, r0, c1, c0, 1 "); + asm("mcr p15, 0, r8, c7, c10, 4 "); // DSB + asm("mcr p15, 0, r8, c7, c5, 4 "); // ISB + asm("ldmfd sp!, {r4-r12,pc} "); + } +#endif diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/specific/variant.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/specific/variant.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,799 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\specific\variant.cpp +* +*/ + + + +#include "variant.h" +#include "mconf.h" +#include +#include +#include "ne1_tb_power.h" +#include +#include + +//These constants define Custom Restart Reasons in SuperPage::iHwStartupReason +const TUint KHtCustomRestartMax = 0xff; +const TUint KHtCustomRestartShift = 8; +const TUint KHtCustomRestartMask = KHtCustomRestartMax << KHtCustomRestartShift; + +const TUint KHtRestartStartupModesMax = 0xf; // Variable, platform dependant +//const TUint KHtRestartStartupModesShift = 16; // Variable, platform dependant +//const TUint KHtRestartStartupModesMask = KHtRestartStartupModesMax << KHtRestartStartupModesShift; + +void NE1_TBVariantFault(TInt aLine) + { + Kern::Fault("NE1_TBVariant",aLine); + } + +#define V_FAULT() NE1_TBVariantFault(__LINE__) + +// Debug output +#define XON 17 +#define XOFF 19 +#define DEBUG_XON_XOFF 0 // Non-zero if we want XON-XOFF handshaking + +GLDEF_D NE1_TBVariant TheVariant; +TUint32 Variant::iBaseAddress=0; + +TUint32 NE1_TBVariant::HandlerData[3]; +SInterruptHandler NE1_TBVariant::Handlers[ENumXInts]; + +extern void XIntDispatch(TAny*); + +#ifdef __SMP__ + +extern void PowerUpCpu(TInt aCpu, SPerCpuUncached* aU); +extern void PowerDownCpu(TInt aCpu, SPerCpuUncached* aU); + +extern "C" { +SVariantInterfaceBlock VIB; + +SVariantInterfaceBlock* InitVIB() + { + SVariantInterfaceBlock* v = &VIB; + v->iVer = 0; + v->iSize = sizeof(VIB); + v->iMaxCpuClock = UI64LIT(400000000); // 400MHz + v->iMaxTimerClock = 200000000u; // 200MHz = CPU CLK / 2 + v->iScuAddr = KHwBaseSCU; + v->iGicDistAddr = KHwBaseGlobalIntDist; + v->iGicCpuIfcAddr = KHwBaseIntIf; + v->iLocalTimerAddr = KHwBaseSCU + 0x600u; + v->iCpuPowerUpFn = &PowerUpCpu; + v->iCpuPowerDownFn = &PowerDownCpu; + return v; + } +} + +#endif + +extern "C" EXPORT_C TAny* VariantInitialise(TInt a) + { + switch(a) + { + case 0: return &TheVariant; +#ifdef __SMP__ + case 1: return InitVIB(); +#endif + default: return 0; + } + } + +NE1_TBVariant::NE1_TBVariant() + { +#ifdef __SMP__ + __VARIANT_SUPPORTS_NANOKERNEL_INTERFACE_BLOCK__(); +#endif + iDebugInitialised=EFalse; + } + +// +// TO DO: (optional) +// +// Specify the RAM zone configuration. +// +// 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] = +// iBase iSize iID iPref iFlags +// { +// __SRAM_ZONE(0x????????, 0x???????, ?, ?, ?), +// ... +// __SRAM_ZONE(0x????????, 0x???????, ?, ?, ?), +// __SRAM_ZONE_END, // end of zone list +// }; +// + +TInt NE1_TBVariant::RamZoneCallback(TRamZoneOp aOp, TAny* aId, const TAny* aMasks) + { + // + // TO DO: (optional) + // + // Handle RAM zone operations requested by the kernel. + // + return TheVariant.DoRamZoneCallback(aOp, (TUint)aId, (const TUint*)aMasks); + } + + +TInt NE1_TBVariant::DoRamZoneCallback(TRamZoneOp aOp, TUint aId, const TUint* aMasks) + { + // + // TO DO: (optional) + // + // Handle RAM zone operations requested by the kernel. + // + // Three types of operation need to be supported: + // ERamZoneOp_Init: Update power state of the RAM zones after the + // kernel has initialised. + // 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: + break; + case ERamZoneOp_PowerUp: + break; + case ERamZoneOp_PowerDown: + break; + default: + return KErrNotSupported; + } + return KErrNone; + } + + +void NE1_TBVariant::Init1() + { + __KTRACE_OPT(KBOOT,Kern::Printf("NE1_TBVariant::Init1()")); + + // + // TO DO: (mandatory) + // + // Configure Memory controller and Memrory Bus parameters (in addition to what was done in the Bootstrap) + // + __KTRACE_OPT(KBOOT,Kern::Printf("Memory Configuration done")); + + // + // TO DO: (optional) + // + // Inform the kernel of the RAM zone configuration via Epoc::SetRamZoneConfig(). + // For devices that wish to reduce power consumption of the RAM IC(s) the callback functions + // RamZoneCallback() and DoRamZoneCallback() will need to be implemented and passed + // to Epoc::SetRamZoneConfig() as the parameter aCallback. + // The kernel will assume that all RAM ICs are fully intialised and ready for use from boot. + // + + // + // TO DO: (optional) + // + // Initialise other critical hardware functions such as I/O interfaces, etc, not done by Bootstrap + // + // if CPU is Sleep-capable, and requires some preparation to be put in that state (code provided in Bootstrap), + // the address of the idle code is writen at this location by the Bootstrap + // e.g. + // iIdleFunction=*(TLinAddr*)((TUint8*)&Kern::SuperPage()+0x1000); + // + NaviEngineAssp::Init1(); + + } + +#ifdef __SMP__ +void NE1_TBVariant::Init2AP() + { + __KTRACE_OPT(KBOOT,Kern::Printf("NE1_TBVariant::Init2AP()")); + } +#endif + +void NE1_TBVariant::Init3() + { + __KTRACE_OPT(KBOOT,Kern::Printf(">NE1_TBVariant::Init3()")); + + NaviEngineAssp::Init3(); + + Variant::Init3(); + // + // TO DO: (optional) + // + // Initialise other accessor classes, if required + // + + InitInterrupts(); + __KTRACE_OPT(KBOOT,Kern::Printf("Variant::Init3")); + + // + // TO DO: (optional) + // + // Initialise any Variant class data members here, map in Variant and external hardware addresses + // + DPlatChunkHw* pC=NULL; + TInt r=DPlatChunkHw::New(pC,KHwVariantPhysBase,0x2000,EMapAttrSupRw|EMapAttrFullyBlocking); + __KTRACE_OPT(KHARDWARE, Kern::Printf("r=%d", r)); + __ASSERT_ALWAYS(r==KErrNone,V_FAULT()); + iBaseAddress=pC->LinearAddress(); + __KTRACE_OPT(KHARDWARE, Kern::Printf("iBaseAddress=%08x", iBaseAddress)); + __KTRACE_OPT(KHARDWARE, Kern::Printf(" MapSleepMode(aTicksLeft*MsTickPeriod()); + // ... + // Find out the state of some particular resources + // TBool aResourceState = aManager -> GetResourceState(NE1_TBResourceManager::AsynchBinResourceUsedByZOnly); + // TUint aResourceLevel = aManager -> GetResourceLevel(NE1_TBResourceManager::SynchMlResourceUsedByXOnly); + // ... + + extern void __cpu_idle(); + + __cpu_idle(); + } + +TInt NE1_TBVariant::VariantHal(TInt aFunction, TAny* a1, TAny* a2) + { + TInt r=KErrNone; + switch(aFunction) + { + case EVariantHalCurrentNumberOfScreens: + { + TInt numScreens = 1; // Number of screens is fixed to 1 on the NaviEngine + kumemput(a1,&numScreens,sizeof(numScreens)); + break; + } + + case EVariantHalVariantInfo: + { + TVariantInfoV01Buf infoBuf; + TVariantInfoV01& info=infoBuf(); + info.iRomVersion=Epoc::RomHeader().iVersion; + info.iMachineUniqueId.iData[0] = 0x4956414E; + info.iMachineUniqueId.iData[1] = 0x474E4520; + info.iLedCapabilities = 0; + info.iProcessorClockInKHz = 400000; + + // ratio of 'speed' to 'speed' of a Psion Series 5 ... + // ... no I'm not joking! + info.iSpeedFactor = 20; + + Kern::InfoCopy(*(TDes8*)a1,infoBuf); + break; + } + case EVariantHalDebugPortSet: + { + // + // TO DO: (mandatory) + // + // Write the iDebugPort field of the SuperPage, as in the following EXAMPLE ONLY: + // + TUint32 thePort = (TUint32)a1; + switch(thePort) + { + case 0: // port 0 at 115200bps + case 0x100: // port 0 at 230400bps + case 1: // port 1 at 115200bps + case 0x101: // port 1 at 230400bps + case 2: // port 2 at 115200bps + case 3: // ??same as 0?? + TheVariant.iDebugInitialised=EFalse; + case (TUint32)KNullDebugPort: + Kern::SuperPage().iDebugPort = thePort; + break; + default: + r=KErrNotSupported; + } + break; + } + case EVariantHalDebugPortGet: + { + // + // TO DO: (mandatory) + // + // Obtain the Linear address of the Uart used for outputting Debug strings as in the following EXAMPLE ONLY: + // + + TUint32 thePort = TNaviEngine::DebugPortAddr(); + kumemput32(a1, &thePort, sizeof(TUint32)); + break; + } + case EVariantHalSwitches: + { + // + // TO DO: (optional) + // + // Read the state of any switches, as in the following EXAMPLE ONLY: + // + TUint32 x = Variant::Switches(); + kumemput32(a1, &x, sizeof(x)); + break; + } + case EVariantHalLedMaskSet: + { + // + // TO DO: (optional) + // + // Set the state of any on-board LEDs, e.g: + // TUint32 aLedMask=(TUint32)a1; + // Variant::ModifyLedState(~aLedMask,aLedMask); + // + 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)); + // + break; + } + + case EVariantHalCustomRestartReason: + { + //Restart reason is stored in super page + TInt x = (Kern::SuperPage().iHwStartupReason & KHtCustomRestartMask) >> KHtCustomRestartShift ; + kumemput32(a1, &x, sizeof(TInt)); + break; + } + + case EVariantHalCustomRestart: + { + if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EVariantHalCustomRestart"))) + return KErrPermissionDenied; + if ((TUint)a1 > KHtCustomRestartMax) + return KErrArgument; + Kern::Restart((TInt)a1 << KHtCustomRestartShift); + } + break; + + case EVariantHalCaseState: + { + // + // TO DO: (optional) + // + // Read the state of the case, e.g: + // TUint32 x = Variant::CaseState(); + // kumemput32(a1, &x, sizeof(x)); + // + break; + } + + case EVariantHalPersistStartupMode: + { + if (!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetBacklightOn"))) + return KErrPermissionDenied; + + if ((TUint)a1 > KHtRestartStartupModesMax ) // Restart startup mode max value + return KErrArgument; + // + // TO DO: (optional) + // + // Store the restart reason locally, + // which will eventually be picked up by + // the power controller, e.g: + // iCustomRestartReason = (TUint)a1; + break; + } + + + case EVariantHalGetPersistedStartupMode: + { + // + // TO DO: (optional) + // + // Read the restart startup mode, e.g: + // TInt startup = (Kern::SuperPage().iHwStartupReason & KHtRestartStartupModesMask) >> KHtRestartStartupModesShift; + // kumemput32(a1, &startup, sizeof(TInt)); + break; + } + + case EVariantHalGetMaximumCustomRestartReasons: + { + // + // TO DO: (optional) + // + // Read the maximum custom restart reason, e.g: + // kumemput32(a1, &KHtCustomRestartMax, sizeof(TUint)); + break; + } + + + case EVariantHalGetMaximumRestartStartupModes: + { + // + // TO DO: (optional) + // + // Read the maximum restart startup mode, e.g: + // kumemput32(a1, &KHtRestartStartupModesMax, sizeof(TUint)); + break; + } + + case EVariantHalSerialNumber: + { + TInt serialNumber = NE1_TBVariant::GetSerialNumber(); + kumemput(a1,&serialNumber,sizeof(serialNumber)); + break; + } + + case EVariantHalProfilingDefaultInterruptBase: + { + TInt interruptNumber = KIntCpuProfilingDefaultInterruptBase; + kumemput(a1,&interruptNumber,sizeof(interruptNumber)); + break; + } + + default: + r=KErrNotSupported; + break; + } + return r; + } + +TPtr8 NE1_TBVariant::MachineConfiguration() + { + return TPtr8((TUint8*)&Kern::MachineConfig(),sizeof(TActualMachineConfig),sizeof(TActualMachineConfig)); + } + +TInt NE1_TBVariant::VideoRamSize() + { + // + // Return the size of the area of RAM used to store the Video Buffer, as in the following EXAMPLE ONLY: + return FRAME_BUFFER_SIZE(32, 800, 480);//32 bits per pixel + } + +EXPORT_C void Variant::PowerReset() + { + // + // TO DO: (optional) + // + // Reset all power supplies + // + } + +EXPORT_C TUint Variant::Switches() + { + // + // TO DO: (optional) + // + // Read the state of on-board switches + // + return 0; // EXAMPLE ONLY + } + +/****************************************************************************** + * Interrupt handling/dispatch + ******************************************************************************/ +TInt NE1_TBVariant::InterruptBind(TInt anId, TIsr anIsr, TAny* aPtr) + { + TUint id=anId&0x7fffffff; // mask off second-level interrupt mask + if (id>=ENumXInts) + return KErrArgument; + TInt r=KErrNone; + SInterruptHandler& h=Handlers[id]; + TInt irq=NKern::DisableAllInterrupts(); + if (h.iIsr!=Spurious) + r=KErrInUse; + else + { + h.iIsr=anIsr; + h.iPtr=aPtr; + } + NKern::RestoreInterrupts(irq); + return r; + } + +TInt NE1_TBVariant::InterruptUnbind(TInt anId) + { + TUint id=anId&0x7fffffff; // mask off second-level interrupt mask + if (id>=ENumXInts) + return KErrArgument; + InterruptDisable(anId); + InterruptClear(anId); + TInt r=KErrNone; + SInterruptHandler& h=Handlers[id]; + TInt irq=NKern::DisableAllInterrupts(); + if (h.iIsr!=Spurious) + { + h.iIsr=Spurious; + h.iPtr=(TAny*)id; + } + NKern::RestoreInterrupts(irq); + return r; + } + +TInt NE1_TBVariant::InterruptEnable(TInt anId) + { + TUint id=anId&0x7fffffff; // mask off second-level interrupt mask + if (id>=ENumXInts) + return KErrArgument; + TInt r=KErrNone; + SInterruptHandler& h=Handlers[id]; + TInt irq=NKern::DisableAllInterrupts(); + if (h.iIsr==Spurious) + r=KErrNotReady; + else + { + // + // TO DO: (mandatory) + // + // Enable the hardware interrupt in the source, e.g. + // Variant::EnableInt(anId); + // + } + NKern::RestoreInterrupts(irq); + return r; + } + +TInt NE1_TBVariant::InterruptDisable(TInt anId) + { + TUint id=anId&0x7fffffff; // mask off second-level interrupt mask + if (id>=ENumXInts) + return KErrArgument; + // + // TO DO: (mandatory) + // + // Disable the hardware interrupt in the source, e.g. + // Variant::DisableInt(anId); + // + return KErrNone; + } + +TInt NE1_TBVariant::InterruptClear(TInt anId) + { + TUint id=anId&0x7fffffff; + if (id>=ENumXInts) + return KErrArgument; + // + // TO DO: (mandatory) + // + // Clear the hardware interrupt in the source, e.g. + // Variant::ClearInt(anId); + // + return KErrNone; + } + +void NE1_TBVariant::InitInterrupts() + { + if (0) return; + // Set up the variant interrupt dispatcher + + // all interrupts initially unbound + TInt i; + for (i=0; i<(TInt)ENumXInts; i++) + { + Handlers[i].iPtr=(TAny*)i; + Handlers[i].iIsr=Spurious; + } + + // Set up data for 2nd level interrupt dispatcher + HandlerData[0]=Variant::BaseLinAddress(); // Linear Base address of 2nd level Int Controller + HandlerData[1]=(TUint32)&Handlers[0]; // Pointer to handler array + HandlerData[2]=0; // + + // + // TO DO: (mandatory) (NOT MANDATORY - DOESN'T EXIST ON NAVIENGINE) + // + // set up ASSP expansion interrupt to generate interrupts whenever a 2nd level interrupt occurrs + // + + // bind NE1_TBVariant ASSP expansion interrupt input to our interrupt dispatcher +// TInt r=Interrupt::Bind(KIntIdExpansion, XIntDispatch, HandlerData); +// __ASSERT_ALWAYS(r>=0,V_FAULT()); +// Interrupt::Enable(KIntIdExpansion); // enable expansion interrupt + } + +void NE1_TBVariant::Spurious(TAny* aId) + { + TUint32 id=((TUint32)aId)|0x80000000u; + Kern::Fault("SpuriousInt",id); + } + + +// USB Client controller + +TBool NE1_TBVariant::UsbClientConnectorDetectable() + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("NE1_TBVariant::UsbClientConnectorDetectable")); + + // TO DO: The return value should reflect the actual situation. + return ETrue; + } + + +TBool NE1_TBVariant::UsbClientConnectorInserted() + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("NE1_TBVariant::UsbClientConnectorInserted")); + + // TO DO: Query cable status here. The return value should reflect the actual current state. + return ETrue; + } + + +TInt NE1_TBVariant::RegisterUsbClientConnectorCallback(TInt (*aCallback)(TAny*), TAny* aPtr) + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("NE1_TBVariant::RegisterUsbClientConnectorCallback")); + + iUsbClientConnectorCallback = aCallback; + iUsbClientConnectorCallbackArg = aPtr; + + // TO DO: Register and enable the interrupt(s) for detecting USB cable insertion/removal here. + // (Register UsbClientConnectorIsr.) + + // TO DO: The return value should reflect the actual situation. + return KErrNone; + } + + +void NE1_TBVariant::UnregisterUsbClientConnectorCallback() + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("NE1_TBVariant::UnregisterUsbClientConnectorCallback")); + + // TO DO: Disable and unbind the interrupt(s) for detecting USB cable insertion/removal here. + + iUsbClientConnectorCallback = NULL; + iUsbClientConnectorCallbackArg = NULL; + } + + +TBool NE1_TBVariant::UsbSoftwareConnectable() + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("NE1_TBVariant::UsbSoftwareConnectable")); + + // TO DO: The return value should reflect the actual situation. + return ETrue; + } + + +TInt NE1_TBVariant::UsbConnect() + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("NE1_TBVariant::UsbConnect")); + + // TO DO: Do here whatever is necessary for the UDC to appear on the bus (and thus to the host). + + return KErrNone; + } + + +TInt NE1_TBVariant::UsbDisconnect() + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("NE1_TBVariant::UsbDisconnect")); + + // TO DO: Do here whatever is necessary for the UDC to appear disconnected from the bus (and thus from the + // host). + + return KErrNone; + } + + +void NE1_TBVariant::UsbClientConnectorIsr(TAny *aPtr) +// +// Services the USB cable interrupt. +// + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("NE1_TBVariant::UsbClientConnectorIsr()")); + + NE1_TBVariant* tm = static_cast(aPtr); + + // TO DO: Service interrupt here: determmine cause, clear condition flag (if applicable), etc. + + if (tm->UsbClientConnectorInserted()) + { + __KTRACE_OPT(KHARDWARE, Kern::Printf(" > USB cable now inserted.")); + } + else + { + __KTRACE_OPT(KHARDWARE, Kern::Printf(" > USB cable now removed.")); + } + + // Important: Inform the USB stack. + if (tm->iUsbClientConnectorCallback) + { + (*tm->iUsbClientConnectorCallback)(tm->iUsbClientConnectorCallbackArg); + } + } + +// Set the board serial number +EXPORT_C TUint16 NE1_TBVariant::SetSerialNumber( TUint32 aSerialNum ) + { + TheVariant.iSerialNumber = aSerialNum; + return KErrNone; + } + +// Get the board serial number +EXPORT_C TUint32 NE1_TBVariant::GetSerialNumber( ) + { + return TheVariant.iSerialNumber; + } + + +#ifdef __SMP__ + +void PowerUpCpu(TInt aCpu, SPerCpuUncached* aU) + { + __KTRACE_OPT(KHARDWARE,Kern::Printf("PowerUpCpu %d %08x", aCpu, aU)); + aU->iPowerOnReq = 0xF000000Fu; // special value + __e32_io_completion_barrier(); + __holler(); + } + +void PowerDownCpu(TInt aCpu, SPerCpuUncached* aU) + { + __KTRACE_OPT(KHARDWARE,Kern::Printf("PowerDownCpu %d %08x", aCpu, aU)); + } + +#endif + +//---eof diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/specific/xyin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/specific/xyin.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,1157 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb\Specific\xyin.cpp +* Implementation of a digitiser (touch-screen) driver. +* This code assumes that an interrupt is generated on pen-down and pen-up events. +* This file is part of the NE1_TBVariant Base port +* We use this driver to exemplify the usage of Resource Management for shared resources, Peripheral "Sleep" +* and detection and notification of Wakeup events +* +*/ + + + + +#include +#include +#include +#include "mconf.h" +#include +#include "lcdgce.h" + +#ifdef USE_PEN_INTERRUPTS +#include +const TUint KLcdInterruptPin = 22; +#else +const TUint KPenEventsPollTime = 30; +#endif + +// digitiser origin & size in pixels +const TUint KConfigXyOffsetX = 0; // digitiser origin - same as display area +const TUint KConfigXyOffsetY = 0; + +// digitiser dimensions in digitiser co-ordinates +const TInt KConfigXySpreadX = 3600; // maximum valid X spread +const TInt KConfigXySpreadY = 3600; // maximum valid Y spread +const TInt KConfigXyMinX = 450; // minimum valid X value +const TInt KConfigXyMinY = 450; // minimum valid Y value +const TUint KXYShift = 4100; + +const TInt KDigitiserThreadPriority = 26; +_LIT(KDigitiserDriverThreadName,"DigitizerThread"); + +// Define a 2x2 matrix and two constants Tx and Ty to convert digitiser co-ordinates +// to pixels such that +// +// (X<<16 Y<<16) = (x y) x (R11 R12) + (Tx Ty) +// (R21 R22) +// or : +// +// X = (x*R11 + y*R21 + TX) >> 16; +// Y = (x*R12 + y*R22 + TY) >> 16; + +// +// where x,y are digitiser coordinates, Tx,Ty are constant offsets and X,Y are screen +// coordinates. Left shifting by 16 bits is used so as not to lose precision. + +// After taking a sample, wait for the specified number of nano-kernel ticks (normally 1 ms) +// before taking the next sample +const TInt KInterSampleTime = 1; + +// After a group of samples has been processed by the DDigitiser::ProcessRawSample() DFC, +// wait for the specified number of nano-kernel ticks before taking the next sample +const TInt KInterGroupTime = 1; + +// After a pen-down interrupt, +// wait for the specified number of nano-kernel ticks before taking the next sample +const TInt KPenDownDelayTime = 2; + +// If powering up the device with the pen down, +// wait for the specified number of nano-kernel ticks before taking the next sample +const TInt KPenUpPollTime = 30; + +// After a pen-up interrupt, +// wait for the specified number of nano-kernel ticks before calling PenUp() +const TInt KPenUpDebounceTime = 10; + +// number of samples to discard on pen-down +const TInt KConfigXyPenDownDiscard = 1; + +// number of samples to discard on pen-up +const TInt KConfigXyPenUpDiscard = 1; + +// offset in pixels to cause movement in X direction +const TInt KConfigXyAccThresholdX = 12; + +// offset in pixels to cause movement in Y direction +const TInt KConfigXyAccThresholdY = 12; + +// number of samples to average - MUST be <= KMaxXYSamples +const TInt KConfigXyNumXYSamples = 4; + +// disregard extremal values in each 4-sample group +const TBool KConfigXyDisregardMinMax= ETrue; //EFalse; + +// Registers.. +const TUint KHwPenInterruptRegister = KHwFPGABase + 0x0408; // LCD penInterrupt register +const TUint KHwTSPStart = KHwFPGABase + 0x0608; // TSP Control Register.. +const TUint KHwTSPXData = KHwFPGABase + 0x0610; // TSP X Data Register.. +const TUint KHwTSPYData = KHwFPGABase + 0x0618; // TSP Y Data Register.. + +// obsolete constants : +const TInt KConfigXyDriveXRise = 0; +const TInt KConfigXyDriveYRise = 0; +const TInt KConfigXyMaxJumpX = 0; +const TInt KConfigXyMaxJumpY = 0; + + +struct SConfig + { + TUint iConfigXyWidth; + TUint iConfigXyHeight; + TBool iLandscape; + + // Calibration Values + TInt iConfigXyR11; + TInt iConfigXyR12; + TInt iConfigXyR21; + TInt iConfigXyR22; + TInt iConfigXyTx; + TInt iConfigXyTy; + }; + +enum TTouchScreenMode + { + TOUCHSCREEN_MODE_NEC_WVGA = 0, + TOUCHSCREEN_MODE_HITACHI_VGA, + TOUCHSCREEN_MODE_HITACHI_QVGA, + + TOUCHSCREEN_MODE_NONE = 255, + }; + +static const SConfig Mode_Config[]= + { + // NEC WVGA - default mode + { + 800, + 480, + ETrue, + + // Calibration values; these are set manually using the TechView calibration app + 17722, // R11 + 1239, // R12 + 399, // R21 + 12352, // R22 + -11623449, // Tx + -10468471, // Ty + }, + + + // LCD, Portrait VGA + { + 480, + 640, + EFalse, + + // Calibration values; these are set manually using the TechView calibration app + 11346, // R11 + 538, // R12 + -682, // R21 + 14703, // R22 + -5683258, // Tx + -9913475, // Ty + }, + + // LCD, Portrait QVGA + { + 240, + 320, + EFalse, + + // Calibration values; these are set manually using the TechView calibration app + 5873, //iConfigXyR11; + 651, //iConfigXyR12; + -250, //iConfigXyR21; + 7366, //iConfigXyR22; + -3591097, //iConfigXyTx; + -5181791, //iConfigXyTy; + }, + }; + + +/****************************************************** + * Main Digitiser Class + ******************************************************/ +NONSHARABLE_CLASS(DNE1_TBDigitiser) : public DDigitiser + { +public: + enum TState + { + E_HW_PowerUp, + E_HW_PenUpDebounce, + E_HW_CollectSample + }; + +public: + // from DDigitiser - initialisation + DNE1_TBDigitiser(); + virtual TInt DoCreate(); + void SetDefaultConfig(); + + // from DDigitiser - signals to hardware-dependent code + virtual void WaitForPenDown(); + virtual void WaitForPenUp(); + virtual void WaitForPenUpDebounce(); + virtual void DigitiserOn(); + virtual void DigitiserOff(); + virtual void FilterPenMove(const TPoint& aPoint); + virtual void ResetPenMoveFilter(); + + // from DDigitiser - machine-configuration related things + virtual TInt DigitiserToScreen(const TPoint& aDigitiserPoint, TPoint& aScreenPoint); + virtual void ScreenToDigitiser(TInt& aX, TInt& aY); + virtual TInt SetXYInputCalibration(const TDigitizerCalibration& aCalibration); + virtual TInt CalibrationPoints(TDigitizerCalibration& aCalibration); + virtual TInt SaveXYInputCalibration(); + virtual TInt RestoreXYInputCalibration(TDigitizerCalibrationType aType); + virtual void DigitiserInfo(TDigitiserInfoV01& aInfo); + + // from DPowerHandler + virtual void PowerDown(TPowerState); + virtual void PowerUp(); + + // implementation + void TakeSample(); + void PenInterrupt(); + void DigitiserPowerUp(); + void PowerUpDfc(); + + // callbacks + static void TimerExpired(TAny* aPtr); + static void TimerIntExpired(TAny* aPtr); + static void PenIsr(TAny* aPtr); + static void TakeReading(TAny* aPtr); + static void PowerDown(TAny* aPtr); + static void PowerUp(TAny* aPtr); + +private: + NTimer iTimer; + NTimer iTimerInt; + TDfc iTakeReadingDfc; + TDfc iPowerDownDfc; + TDfc iPowerUpDfc; + TInt iSamplesCount; + TState iState; + TUint8 iPoweringDown; + TSize iScreenSize; +#ifndef USE_PEN_INTERRUPTS + NTimer iPollingTimer; +#endif + TActualMachineConfig& iMachineConfig; + TTouchScreenMode iCurrentMode; + TInt iInterruptId; + }; + +/****************************************************** + * Digitiser main code + ******************************************************/ +/** +Sample timer callback +Schedules a DFC to take a sample + +@param aPtr a pointer to DNE1_TBDigitiser +*/ +void DNE1_TBDigitiser::TimerExpired(TAny* aPtr) + { + DNE1_TBDigitiser* pD=(DNE1_TBDigitiser*)aPtr; + __KTRACE_OPT(KHARDWARE, Kern::Printf("TimerExpired")); + pD->iTakeReadingDfc.Add(); + } + +/** +Debounce timer callback +schedules a DFC to process a pen-down interrupt + +@param aPtr a pointer to DNE1_TBDigitiser +*/ +void DNE1_TBDigitiser::TimerIntExpired(TAny* aPtr) + { + DNE1_TBDigitiser* pD=(DNE1_TBDigitiser*)aPtr; + __KTRACE_OPT(KHARDWARE, Kern::Printf("TIntExpired")); + pD->iTakeReadingDfc.Add(); + } + +/** +Pen-up/down interrupt handler + +@param aPtr a pointer to DNE1_TBDigitiser +*/ +void DNE1_TBDigitiser::PenIsr(TAny* aPtr) + { + DNE1_TBDigitiser* pD=(DNE1_TBDigitiser*)aPtr; + + //check the status of the interrupt: + TUint16 status = AsspRegister::Read16(KHwPenInterruptRegister); + + if (!(status & 0x100)) // Pen is down.. + { +#ifdef USE_PEN_INTERRUPTS + GPIO::DisableInterrupt(pD->iInterruptId); +#endif + pD->PenInterrupt(); + } + +#ifndef USE_PEN_INTERRUPTS + // kick-off the timer again.. + pD->iPollingTimer.Again(KPenEventsPollTime); +#endif + + } + +/** +DFC for taking a sample + +@param aPtr a pointer to DNE1_TBDigitiser +*/ +void DNE1_TBDigitiser::TakeReading(TAny* aPtr) + { + DNE1_TBDigitiser* pD=(DNE1_TBDigitiser*)aPtr; + pD->TakeSample(); + } + +/** +DFC for powering down the device + +@param aPtr a pointer to DNE1_TBDigitiser +*/ +void DNE1_TBDigitiser::PowerDown(TAny* aPtr) + { + DNE1_TBDigitiser* pD=(DNE1_TBDigitiser*)aPtr; + pD->DigitiserOff(); + } + +/** +DFC for powering up the device + +@param aPtr a pointer to DNE1_TBDigitiser +*/ +void DNE1_TBDigitiser::PowerUp(TAny* aPtr) + { + DNE1_TBDigitiser* pD=(DNE1_TBDigitiser*)aPtr; + pD->PowerUpDfc(); + } + + +/** +Creates a new instance of DDigitiser. +Called by extension entry point (PIL) to create a DDigitiser-derived object. + +@return a pointer to a DNE1_TBDigitiser object +*/ +DDigitiser* DDigitiser::New() + { + return new DNE1_TBDigitiser; + } + +/** +Default constructor +*/ +DNE1_TBDigitiser::DNE1_TBDigitiser() : + iTimer(TimerExpired,this), + iTimerInt(TimerIntExpired,this), + iTakeReadingDfc(TakeReading,this,5), + iPowerDownDfc(PowerDown,this,5), + iPowerUpDfc(PowerUp,this,5), +#ifndef USE_PEN_INTERRUPTS + iPollingTimer(PenIsr, this), +#endif + iMachineConfig(TheActualMachineConfig()) + { + } + +/** +Perform hardware-dependent initialisation + +Called by platform independent layer +*/ +TInt DNE1_TBDigitiser::DoCreate() + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("DNE1_TBDigitiser::DoCreate")); + if (Kern::ColdStart()) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Resetting digitiser calibration")); + + // Emergency digitiser calibration values + TInt mode = ReadDipSwitchDisplayMode(); + switch (mode) + { + case DISPLAY_MODE_HITACHI_VGA: // Hitachi display in VGA + iCurrentMode = TOUCHSCREEN_MODE_HITACHI_VGA; + break; + case DISPLAY_MODE_HITACHI_QVGA: // Hitachi display in QVGA + iCurrentMode = TOUCHSCREEN_MODE_HITACHI_QVGA; + break; + case DISPLAY_MODE_NEC_WVGA: // NEC display in WVGA + iCurrentMode = TOUCHSCREEN_MODE_NEC_WVGA; + break; + + // In all ANALOG modes - don't use the digitiser + case DISPLAY_MODE_ANALOG_VGA: + case DISPLAY_MODE_ANALOG_QVGA_LANDSCAPE_OLD: + case DISPLAY_MODE_ANALOG_QVGA_PORTRAIT: + case DISPLAY_MODE_ANALOG_QVGA_LANDSCAPE: + iCurrentMode = TOUCHSCREEN_MODE_NONE; + break; + + default: // In all other modes, use the NEC WVGA settings + iCurrentMode = TOUCHSCREEN_MODE_NEC_WVGA; + break; + + } + iMachineConfig.iCalibration.iR11 = Mode_Config[iCurrentMode].iConfigXyR11; + iMachineConfig.iCalibration.iR12 = Mode_Config[iCurrentMode].iConfigXyR12; + iMachineConfig.iCalibration.iR21 = Mode_Config[iCurrentMode].iConfigXyR21; + iMachineConfig.iCalibration.iR22 = Mode_Config[iCurrentMode].iConfigXyR22; + iMachineConfig.iCalibration.iTx = Mode_Config[iCurrentMode].iConfigXyTx; + iMachineConfig.iCalibration.iTy = Mode_Config[iCurrentMode].iConfigXyTy; + } + + TDynamicDfcQue* dfcq; + // Create a dedicated DFC queue for this driver + TInt r = Kern::DynamicDfcQCreate(dfcq, KDigitiserThreadPriority, KDigitiserDriverThreadName); + if (r != KErrNone) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Could not create a DFCQue, r %d", r)); + return r; + } + +#ifdef CPU_AFFINITY_ANY + NKern::ThreadSetCpuAffinity((NThread*)(iDfcQ->iThread), KCpuAffinityAny); +#endif + + // and DFCs to use it.. + iDfcQ = dfcq; + iTakeReadingDfc.SetDfcQ(iDfcQ); + iPowerDownDfc.SetDfcQ(iDfcQ); + iPowerUpDfc.SetDfcQ(iDfcQ); + + + // stop at this point, if the LCD panel is not present + if (iCurrentMode == TOUCHSCREEN_MODE_NONE) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("xyin.cpp: LCD panel not switched on...\nwill not start the driver")); + return KErrNone; + } + + // register power handler + Add(); + DigitiserPowerUp(); + +#ifdef USE_PEN_INTERRUPTS + // set up interrupts + iInterruptId = KLcdInterruptPin; + r = GPIO::BindInterrupt(iInterruptId, PenIsr, this); + if (r != KErrNone) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Error binding the interrupt: r %d", r)); + return r; + } +#endif + + // set up the default configuration + SetDefaultConfig(); + + return KErrNone; + } + +/** +Initialise the DDigitiser::iCfg structure +*/ +void DNE1_TBDigitiser::SetDefaultConfig() + { + iCfg.iPenDownDiscard = KConfigXyPenDownDiscard; // number of samples to discard on pen-down + iCfg.iPenUpDiscard = KConfigXyPenUpDiscard; // number of samples to discard on pen-up + iCfg.iDriveXRise = KConfigXyDriveXRise; // number of milliseconds to wait when driving horizontal edges + iCfg.iDriveYRise = KConfigXyDriveYRise; // number of milliseconds to wait when driving vertical edges + iCfg.iMinX = KConfigXyMinX; // minimum valid X value + iCfg.iMaxX = KConfigXySpreadX - 1; // maximum valid X value + iCfg.iSpreadX = KConfigXySpreadX; // maximum valid X spread + iCfg.iMinY = KConfigXyMinY; // minimum valid Y value + iCfg.iMaxY = KConfigXySpreadY - 1; // maximum valid Y value + iCfg.iSpreadY = KConfigXySpreadY; // maximum valid Y spread + iCfg.iMaxJumpX = KConfigXyMaxJumpX; // maximum X movement per sample (pixels) + iCfg.iMaxJumpY = KConfigXyMaxJumpY; // maximum Y movement per sample (pixels) + iCfg.iAccThresholdX = KConfigXyAccThresholdX; // offset in pixels to cause movement in X direction + iCfg.iAccThresholdY = KConfigXyAccThresholdY; // offset in pixels to cause movement in Y direction + iCfg.iNumXYSamples = KConfigXyNumXYSamples; // number of samples to average + iCfg.iDisregardMinMax = KConfigXyDisregardMinMax; // disregard extremal values in each 4-sample group + } + +/** +Takes a sample from the digitiser. +Called in the context of a DFC thread. +*/ +void DNE1_TBDigitiser::TakeSample() + { +// TNE1_TBPowerController::WakeupEvent(); // notify of pendown (wakeup event) and let the power controller sort + // out if it needs propagation + TBool penDown = EFalse; + + //check the touch panel interrupt state + TUint16 status = AsspRegister::Read16(KHwPenInterruptRegister); + if(!(status & 0x100)) //Panel touched + penDown = ETrue; + + __KTRACE_OPT(KHARDWARE,Kern::Printf("TS: S%d PD%d Sp%d", (TInt)iState, penDown?1:0, iSamplesCount)); + + if (iState==E_HW_PowerUp) + { + // waiting for pen to go up after switch on due to pen down or through the HAL + if (!penDown) // pen has gone up -> transition to new state + { + iState=E_HW_CollectSample; + iSamplesCount=0; // reset sample buffer +#ifdef USE_PEN_INTERRUPTS + // clear and enable pen-down interrupt + GPIO::EnableInterrupt(iInterruptId); +#endif + } + else // pen is still down, wait a bit longer in this state + { + iTimer.OneShot(KPenUpPollTime); + } + return; + } + + if (!penDown) + { + if (iState==E_HW_PenUpDebounce) + { + iState=E_HW_CollectSample; // back to initial state, no samples collected + iSamplesCount=0; // reset sample buffer + iPenUpDfc.Enque(); + } + else // iState=E_HW_CollectSample + { + iState=E_HW_PenUpDebounce; + iTimer.OneShot(KPenUpDebounceTime); // wait a bit to make sure pen still up + } + return; + } + else if (iState==E_HW_PenUpDebounce) // pen down + { + // false alarm - pen is down again + iState=E_HW_CollectSample; // take a new set of samples + iSamplesCount=0; // reset sample buffer + } + // default: pen down and iState=E_HW_CollectSample + // Read from appropriate hardware register to get the current digitiser coordinates + // of the point that is being touched + + //start A/D conversion + AsspRegister::Write16(KHwTSPStart, 1); + + // and wait for its completion(0x1 bit should be cleared) + TUint timeout=100; + while((AsspRegister::Read16(KHwPenInterruptRegister)&0x1) && --timeout); + + // Read values (Reading will clear interrupt status) + TInt16 X = AsspRegister::Read16(KHwTSPXData); + TInt16 Y = AsspRegister::Read16(KHwTSPYData); + + if(Mode_Config[iCurrentMode].iLandscape) + { + iX[iSamplesCount] = KXYShift - X; + iY[iSamplesCount] = Y; + } + else + { + iX[iSamplesCount] = KXYShift - X; + iY[iSamplesCount] = KXYShift - Y; + } + + __KTRACE_OPT(KHARDWARE,Kern::Printf("Raw: X=%d Y=%d",iX[iSamplesCount],iY[iSamplesCount])); + + // count samples collected - if it's less than minimum, + // schedule the reading of another sample + if (++iSamplesCount < iCfg.iNumXYSamples) // iX[] and iY[] are 4 levels deep in xyin.h... + { + if(KInterSampleTime > 0) + { + iTimer.OneShot(KInterSampleTime); // haven't got a complete group yet, so queue timer to sample again + } + else + { + iTakeReadingDfc.Enque(); + } + return; + } + + // Have a complete group of samples so pass up to processing layer (PIL) + iSampleDfc.Enque(); // adds DFC + + } + +/** +Request for an interrupt to be generated when the pen is next down +Called by PIL at startup or when pen leaves digitiser after pen-up event issued +*/ +void DNE1_TBDigitiser::WaitForPenDown() + { + // Called at startup or when pen leaves digitiser after pen-up event issued + __KTRACE_OPT(KHARDWARE,Kern::Printf("WD: PowerDownMask %x",iPoweringDown)); + if (iPoweringDown) + { + // powering down + + // Enable touch panel interrupt to allow the hardware + // to detect when the digitiser panel is touched and wakes up the system if in standby + AsspRegister::Write16(KHwPenInterruptRegister, 0); + + // Relinquish request on power resources + //... + + iPoweringDown = EFalse; + PowerDownDone(); + } + else + { + if (!iTimer.IsPending() && + !iTimerInt.IsPending() && + iCurrentMode != TOUCHSCREEN_MODE_NONE) + { +#ifndef USE_PEN_INTERRUPTS + iPollingTimer.OneShot(KPenEventsPollTime,ETrue); +#else + // enable pen-down interrupt + GPIO::EnableInterrupt(iInterruptId); +#endif + } + } + } + +/** +Called by PIL after it has processed a group of raw samples while pen is down. +Used to indicate that the iX, iY buffers may be re-used +*/ +void DNE1_TBDigitiser::WaitForPenUp() + { + __KTRACE_OPT(KHARDWARE,Kern::Printf("WU")); + iState = E_HW_CollectSample; + iSamplesCount = 0; // reset sample buffer + if(KInterGroupTime > 0) // need to check this config param as it might be zero! + iTimer.OneShot(KInterGroupTime); + else + iTakeReadingDfc.Enque(); + + } + +/** +Called by PIL if the group of samples collected is not good enough +Used to indicate that the iX, iY buffers may be re-used +*/ +void DNE1_TBDigitiser::WaitForPenUpDebounce() + { + __KTRACE_OPT(KHARDWARE,Kern::Printf("WUDB")); + iState = E_HW_CollectSample; + iSamplesCount = 0; // reset sample buffer + if(KInterGroupTime > 0) // need to check this config param as it might be zero! + iTimer.OneShot(KInterGroupTime); + else + iTakeReadingDfc.Enque(); + } + +/** +Pen up/down interrupt service routine (ISR) +*/ +void DNE1_TBDigitiser::PenInterrupt() + { + __KTRACE_OPT(KHARDWARE, Kern::Printf("PenInterrupt")); + + if (KPenDownDelayTime>0) // need to check this config param as it might be zero! + iTimerInt.OneShot(KPenDownDelayTime); // start a debounce timer which will queue a DFC to process the interrupt + else + { + iTakeReadingDfc.Add(); + } + } + +/** +DPowerHandler pure virtual +*/ +void DNE1_TBDigitiser::PowerUp() + { + iPowerUpDfc.Enque(); // queue a DFC in this driver's context + } + +/** +Called by power up DFC +*/ +void DNE1_TBDigitiser::PowerUpDfc() + { + __KTRACE_OPT(KPOWER, Kern::Printf("DNE1_TBDigitiser::PowerUpDfc()")); + DigitiserOn(); + PowerUpDone(); // must be called from a different thread than PowerUp() + } + +/** +Turn the digitiser on +May be called as a result of a power transition or from the HAL +If called from HAL, then the digitiser may be already be on (iPointerOn == ETrue) +*/ +void DNE1_TBDigitiser::DigitiserOn() + { + __KTRACE_OPT(KPOWER,Kern::Printf("DNE1_TBDigitiser::DigitiserOn() iPointerOn=%d", iPointerOn)); + + if (!iPointerOn) // may have been powered up already + DigitiserPowerUp(); + } + +/** +Power-up the digitiser. Assumes digitiser is off. +*/ +void DNE1_TBDigitiser::DigitiserPowerUp() + { + __KTRACE_OPT(KPOWER, Kern::Printf("DigitiserPowerUp")); + iPointerOn = ETrue; // now turned on + + // Re-assert request on power resources + // This will move the peripheral hardware out of low power "Sleep" mode back to fully operational + // ... + + // Select Clock by writing clk_div + // (TSP_CLK = 30MHz/((clk_div+1)*2) (should be >=2) + AsspRegister::Write16(KHwTSPBase, 2); + + // ensure, that touch-panel interrupt is enabled + AsspRegister::Write16(KHwPenInterruptRegister, 0); + + iState = E_HW_PowerUp; // so we wait for pen up if necessary + iTakeReadingDfc.Enque(); + } + +/** +DPowerHandler pure virtual + +@param aPowerState the current power state +*/ +void DNE1_TBDigitiser::PowerDown(TPowerState /*aPowerState*/) + { + iPoweringDown = ETrue; + iPowerDownDfc.Enque(); // queue a DFC in this driver's context + } + +/** +Turn the digitiser off +May be called as a result of a power transition or from the HAL +If called from Power Manager, then the digitiser may be already be off (iPointerOn == EFalse) +if the platform is in silent running mode +*/ +void DNE1_TBDigitiser::DigitiserOff() + { + __KTRACE_OPT(KPOWER,Kern::Printf("DNE1_TBDigitiser::DigitiserOff() iPointerOn=%d", iPointerOn)); + if (iPointerOn) // can have been powered down from HAL + { + iPointerOn = EFalse; +#ifdef USE_PEN_INTERRUPTS + GPIO::DisableInterrupt(iInterruptId); +#else + iPollingTimer.Cancel(); +#endif + // disable the digitiser interrupt + AsspRegister::Write16(KHwPenInterruptRegister, 1); + + iTimer.Cancel(); + iTimerInt.Cancel(); + iTakeReadingDfc.Cancel(); + if (iState != E_HW_CollectSample) + { +#ifdef USE_PEN_INTERRUPTS + iPenUpDfc.Add(); +#else + iPenUpDfc.Enque(); +#endif + } + else + { + // + // TO DO: (optional) + // + // Relinquish request on power resources as we are being powered down + // This will place the peripheral hardware in a low power "Sleep" mode which is Interrupt detection capable + // EXAMPLE ONLY + // + // ... + + if (iPoweringDown) // came here through PowerDown + { + iPoweringDown = EFalse; + PowerDownDone(); + } + } + } + else // already powered down (by HAL) + { + if (iPoweringDown) // came here through PowerDown + { + iPoweringDown = EFalse; + PowerDownDone(); + } + } + } + + +/** +Convert digitiser coordinates to screen coordinates + +@param aDigitiserPoint the digitiser coordinates +@param aScreenPoint A TPoint supplied by the caller. + On return, set to the converted screen coordinates in pixels. + +@return KErrNone if successful +*/ +TInt DNE1_TBDigitiser::DigitiserToScreen(const TPoint& aDigitiserPoint, TPoint& aScreenPoint) + { + NKern::LockSystem(); + TInt R11 = iMachineConfig.iCalibration.iR11; + TInt R12 = iMachineConfig.iCalibration.iR12; + TInt R21 = iMachineConfig.iCalibration.iR21; + TInt R22 = iMachineConfig.iCalibration.iR22; + TInt TX = iMachineConfig.iCalibration.iTx; + TInt TY = iMachineConfig.iCalibration.iTy; + NKern::UnlockSystem(); + TInt X = aDigitiserPoint.iX; + TInt Y = aDigitiserPoint.iY; + + aScreenPoint.iX = (X*R11 + Y*R21 + TX) >> 16; + aScreenPoint.iY = (X*R12 + Y*R22 + TY) >> 16; + + __KTRACE_OPT(KHARDWARE, Kern::Printf("DtS: Dp.x %d, Dp.y %d, Sp.x %d, Sp.y %d", X,Y,aScreenPoint.iX,aScreenPoint.iY)); + + return KErrNone; + } + +/** +Convert screen coordinates back into digitiser coordinates +using the current constants from the superpage + +@param aX The screen X coordinate in pixels; On return, set to the digitiser X coordinate. +@param aY The screen Y coordinate in pixels; On return, set to the digitiser Y coordinate. +*/ +void DNE1_TBDigitiser::ScreenToDigitiser(TInt& aX, TInt& aY) + { + + NKern::LockSystem(); + Int64 R11 = iMachineConfig.iCalibration.iR11; + Int64 R12 = iMachineConfig.iCalibration.iR12; + Int64 R21 = iMachineConfig.iCalibration.iR21; + Int64 R22 = iMachineConfig.iCalibration.iR22; + Int64 TX = iMachineConfig.iCalibration.iTx; + Int64 TY = iMachineConfig.iCalibration.iTy; + NKern::UnlockSystem(); + Int64 X = aX; + Int64 Y = aY; + // + // Xd=(Xs<<16)*R22-(Ys<<16)*R21-(TX*R22)+(TY*R21) + // ------------------------------------------- + // (R22*R11)-(R21*R12) + // + // + // Yd=(Xs<<16)*R12-(Ys<<16)*R11-(TX*R12)+(TY*R11) + // ------------------------------------------- + // (R21*R12)-(R22*R11) + // + // where Xd and Yd are digitiser coordinates + // Xs and Ys are supplied screen coordinates + // + X <<= 16; + Y <<= 16; + + Int64 d = Int64(R21) * Int64(R12) - Int64(R22) * Int64(R11); + + Int64 r = (X*R12) - (Y*R11) - (TX*R12) + (TY*R11); + + if (d != 0) + { + r = r/d; + } + else + { + r = 0; + } + + aY = (TInt)r; + + r = (X*R22)-(Y*R21)-(TX*R22)+(TY*R21); + + if (d != 0) + { + r = r/(-d); + } + else + { + r = 0; + } + + aX=(TInt)r; + } + +/** +Calculate values for R11, R12, R21, R22, TX and TY + +@param aCalibration the screen coordinates of points touched +@return KErrNone if successful +*/ +TInt DNE1_TBDigitiser::SetXYInputCalibration(const TDigitizerCalibration& aCalibration) + { + TInt R11,R12,R21,R22,TX,TY; + // + // Get coords of expected points + // + TDigitizerCalibration cal; + TInt ret=CalibrationPoints(cal); + if (ret != KErrNone) + return ret; + + TInt Xp1 = cal.iTl.iX; + TInt Yp1 = cal.iTl.iY; + TInt Xp2 = cal.iBl.iX; + TInt Yp2 = cal.iBl.iY; + TInt Xp3 = cal.iBr.iX; + TInt Yp3 = cal.iBr.iY; + + // + // Get coords of points touched in screen coordinates + // + TInt X1 = aCalibration.iTl.iX; + TInt Y1 = aCalibration.iTl.iY; + TInt X2 = aCalibration.iBl.iX; + TInt Y2 = aCalibration.iBl.iY; + TInt X3 = aCalibration.iBr.iX; + TInt Y3 = aCalibration.iBr.iY; + + + // + // Convert back to raw digitiser coordinates + // + ScreenToDigitiser(X1,Y1); + ScreenToDigitiser(X2,Y2); + ScreenToDigitiser(X3,Y3); + // + // (Y1-Y2)(Xp1-Xp3) - (Y1-Y3)(Xp1-Xp2) + // ----------------------------------- = R11 + // (Y1-Y2)(X1-X3) - (Y1-Y3)(X1-X2) + + Int64 temp; // temporary variable to prevent divide by zero faults + Int64 r = ((Int64(Y1-Y2)*Int64(Xp1-Xp3))-(Int64(Y1-Y3)*Int64(Xp1-Xp2))); + r <<= 16; + temp = (Int64(Y1-Y2) * Int64(X1-X3) - Int64(Y1-Y3) * Int64(X1-X2)); + if (temp == 0) + { + r = 0; + } + else + { + r /= temp; + } + R11 = (TInt)r; + // + // (Y1-Y2)(Yp1-Yp3) - (Y1-Y3)(Yp1-Yp2) + // ----------------------------------- = R12 + // (Y1-Y2)(X1-X3) - (Y1-Y3)(X1-X2) + // + r = ((Int64(Y1-Y2) * Int64(Yp1-Yp3)) - (Int64(Y1-Y3) * Int64(Yp1-Yp2))); + r <<= 16; + temp = (Int64(Y1-Y2) * Int64(X1-X3) - Int64(Y1-Y3) * Int64(X1-X2)); + if (temp == 0) + { + r = 0; + } + else + { + r /= temp; + } + R12 = (TInt)r; + // + // (X1-X3)(Xp2-Xp3) - (X2-X3)(Xp1-Xp3) + // ----------------------------------- = R21 + // (Y2-Y3)(X1-X3) - (Y1-Y3)(X2-X3) + // + r = (((X1-X3) * (Xp2-Xp3)) - ((X2-X3) * (Xp1-Xp3))); + r <<= 16; + temp = (Int64(Y2-Y3) * Int64(X1-X3) - Int64(Y1-Y3) * Int64(X2-X3)); + if (temp == 0) + { + r = 0; + } + else + { + r /= temp; + } + R21=(TInt)r; + // + // (X1-X3)(Yp2-Yp3) - (X2-X3)(Yp1-Yp3) + // ----------------------------------- = R22 + // (Y2-Y3)(X1-X3) - (Y1-Y3)(X2-X3) + // + r = ((Int64(X1-X3) * Int64(Yp2-Yp3)) - (Int64(X2-X3) * Int64(Yp1-Yp3))); + r <<= 16; + temp = (Int64(Y2-Y3) * Int64(X1-X3) - Int64(Y1-Y3) * Int64(X2-X3)); + if (temp==0) + { + r = 0; + } + else + { + r/=temp; + } + R22 = (TInt)r; + // + // TX = Xp1 - X1*R11 - Y1*R21 + // + TX = (Xp1<<16) - (X1*R11) - (Y1*R21); + // + // TY = Yp1 - X1*R12 - Y1*R22 + // + TY = (Yp1<<16) - (X1*R12) - (Y1*R22); + + // + // Write new values into the superpage + // + NKern::LockSystem(); + iMachineConfig.iCalibration.iR11 = R11; + iMachineConfig.iCalibration.iR12 = R12; + iMachineConfig.iCalibration.iR21 = R21; + iMachineConfig.iCalibration.iR22 = R22; + iMachineConfig.iCalibration.iTx = TX; + iMachineConfig.iCalibration.iTy = TY; + NKern::UnlockSystem(); + + return(KErrNone); + } + +/** +Informs the user-side calibration application where to draw +the cross-hairs on the screen + +@param aCalibration On return contains the for points on the screen (in screen coordinates) + where the cross-hairs should be drawn +@return KErrNone if succcessful +*/ +TInt DNE1_TBDigitiser::CalibrationPoints(TDigitizerCalibration& aCalibration) + { + TVideoInfoV01Buf buf; + TVideoInfoV01& vidinfo = buf(); + TInt r = Kern::HalFunction(EHalGroupDisplay, EDisplayHalCurrentModeInfo, (TAny*)&buf, NULL); + if (r != KErrNone) + return r; + iScreenSize=vidinfo.iSizeInPixels; + + aCalibration.iBl.iX = aCalibration.iTl.iX = iScreenSize.iWidth/10; + aCalibration.iTr.iY = aCalibration.iTl.iY = iScreenSize.iHeight/10; + aCalibration.iBr.iY = aCalibration.iBl.iY = iScreenSize.iHeight-iScreenSize.iHeight/10; + aCalibration.iTr.iX = aCalibration.iBr.iX = iScreenSize.iWidth-iScreenSize.iWidth/10; + return r; + } +/** +Saves the digitiser calibration to the persistent machine configuration area +so that it can be restored after a power-down/up + +@return KErrNone if succcessful +*/ +TInt DNE1_TBDigitiser::SaveXYInputCalibration() + { + NKern::LockSystem(); + iMachineConfig.iCalibrationSaved = iMachineConfig.iCalibration; + NKern::UnlockSystem(); + return(KErrNone); + } + +/** +Restores the digitiser calibration from the persistent machine configuration area +following a power-up + +@param aType indicates whether to restore factory or saved settings +@return KErrNone if succcessful +*/ +TInt DNE1_TBDigitiser::RestoreXYInputCalibration(TDigitizerCalibrationType aType) + { + TInt r=KErrNone; + NKern::LockSystem(); + switch (aType) + { + case EFactory: + iMachineConfig.iCalibration = iMachineConfig.iCalibrationFactory; + break; + case ESaved: + iMachineConfig.iCalibration = iMachineConfig.iCalibrationSaved; + break; + default: + r = KErrNotSupported; + break; + } + NKern::UnlockSystem(); + return r; + } + +/** +Gets the digitiser configuration information + +@param aInfo On return, contains information about the digitiser's dimensions etc. +*/ +void DNE1_TBDigitiser::DigitiserInfo(TDigitiserInfoV01& aInfo) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("DNE1_TBDigitiser::DigitiserInfo")); + + if (iCurrentMode != TOUCHSCREEN_MODE_NONE) + { + aInfo.iDigitiserSize.iWidth = Mode_Config[iCurrentMode].iConfigXyWidth; + aInfo.iDigitiserSize.iHeight = Mode_Config[iCurrentMode].iConfigXyHeight; + } + else + { + aInfo.iDigitiserSize.iWidth = 0; + aInfo.iDigitiserSize.iHeight = 0; + } + + aInfo.iOffsetToDisplay.iX = KConfigXyOffsetX; + aInfo.iOffsetToDisplay.iY = KConfigXyOffsetY; + } + +/** +Issues a pen move event if the distance from the last point is greater than the threshold + +@param aPoint the pen position in screen coordinates +*/ +void DNE1_TBDigitiser::FilterPenMove(const TPoint& aPoint) + { + TPoint offset=aPoint; + offset.iX -= iLastPos.iX; + offset.iY -= iLastPos.iY; + if (Abs(offset.iX)>=iCfg.iAccThresholdX || Abs(offset.iY)>=iCfg.iAccThresholdY) + { + iLastPos=aPoint; + IssuePenMoveEvent(aPoint); + } + } + +/** +Reset the pen move filter +*/ +void DNE1_TBDigitiser::ResetPenMoveFilter() + { + } + + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/autoexec.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/autoexec.bat Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,35 @@ +@rem +@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +@rem All rights reserved. +@rem This component and the accompanying materials are made available +@rem under the terms of "Eclipse Public License v1.0" +@rem which accompanies this distribution, and is available +@rem at the URL "http://www.eclipse.org/legal/epl-v10.html". +@rem +@rem Initial Contributors: +@rem Nokia Corporation - initial contribution. +@rem +@rem Contributors: +@rem +@rem Description: +@rem + +trace 2 2 +z: +cd test +format c: +format d: /e +format d: +runtests e32test.auto.bat -st -t 60 -c +format c: +format d: /e +format d: +runtests loader.auto.bat -st -t 2400 -c +format c: +format d: /e +format d: +runtests f32test.auto.bat -d c -st -t 60 -c +format c: +format d: /e +format d: +runtests f32test.auto.bat -d d -st -t 540 -p -c diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/bld.inf Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +PRJ_PLATFORMS +ARM4 ARM4SMP ARMV5 ARMV5SMP + +PRJ_TESTEXPORTS +autoexec.bat /epoc32/rom/ne1_tb/ // + +// Files required for automated nand testing +nandtest_test_autoexec.bat /epoc32/rom/ne1_tb/ // +nandtest_load_autoexec.bat /epoc32/rom/ne1_tb/ // +nandtest_load_wdp_autoexec.bat /epoc32/rom/ne1_tb/ // +nandtest_shortertest_autoexec.bat /epoc32/rom/ne1_tb/ // +nandtest_fulltest_autoexec.bat /epoc32/rom/ne1_tb/ // + +// Files required for automated NAND demand paging testing +nanddemandpaginge32tests.bat /epoc32/rom/ne1_tb/ // + +#if !defined(GCCXML) || !defined(NO_GCCXML) + +PRJ_MMPFILES +mediaext/d_nfe.mmp + +PRJ_TESTMMPFILES + +// Drivers +../../../../../os/kernelhwsrv/kerneltest/e32test/group/d_mstim support +../../../../../os/kernelhwsrv/kerneltest/e32test/group/d_tick support +../../../../../os/kernelhwsrv/kerneltest/e32test/group/d_latncy support +../../../../../os/kernelhwsrv/kerneltest/e32test/group/d_shadow support +../../../../../os/kernelhwsrv/kerneltest/e32test/group/bm_pdd support +../../../../../os/kernelhwsrv/kerneltest/e32test/group/d_cache support +../../../../../os/kernelhwsrv/kerneltest/e32test/hcr/d_hcrext_client support +../../../../../os/kernelhwsrv/kerneltest/e32test/hcr/d_hcrext_own support +d_csi support +d_csi_ctrless support +d_timestamppdd support + +d_frqchg support +d_gpio support +#ifndef SMP +t_csi manual +#endif +t_gpio +#endif + +d_pci support + +t_pci \ No newline at end of file diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/csi/d_csi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/csi/d_csi.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,1445 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifdef STANDALONE_CHANNEL +#include +#include "csi_master.h" +#include "csi_slave.h" +#else +#include +#endif +#include +#include +#include "cs42l51.h" + +#include "d_csi.h" + +#define __KTRACE(s) +//#define __KTRACE(s) __KTRACE_OPT(KIIC, s) + +const TInt KMaxNumChannels = 1; // we only support one client at the time + +// generic check-error macro - to not put this manually on each operation. +#define CHECK_ERR(r) \ + if(r != KErrNone){ \ + __KTRACE(Kern::Printf("d_csi.cpp, line: %d returned r=%d", __LINE__, r)); \ + return r;} + +// Default Test Header +const TConfigSpiV01 DefaultHeader = + { + ESpiWordWidth_8, //iWordWidth + 260000, //iClkSpeed + ESpiPolarityLowRisingEdge, //iClkMode + 500, // iTimeoutPeriod + EBigEndian, // iEndianness + EMsbFirst, //iBitOrder + 0, //iTransactionWaitCycles + ESpiCSPinActiveLow //iCsPinActiveMode + }; + +_LIT(KLddRootName,"d_csi"); +_LIT(KIicClientThreadName,"IicClientLddThread"); + +// Constructor +DDeviceIicClient::DDeviceIicClient() + { + __KTRACE(Kern::Printf("DDeviceIicClient::DDeviceIicClient()")); + iParseMask = 0; // No info, no PDD, no Units + iUnitsMask = 0; + iVersion = TVersion(KIicClientMajorVersionNumber, + KIicClientMinorVersionNumber, KIicClientBuildVersionNumber); + } + +// Destructor +DDeviceIicClient::~DDeviceIicClient() + { + __KTRACE(Kern::Printf("DDeviceIicClient::~DDeviceIicClient()")); + } + +// Install the device driver. +TInt DDeviceIicClient::Install() + { + __KTRACE(Kern::Printf("DDeviceIicClient::Install()")); + return (SetName(&KLddRootName)); + } + +void DDeviceIicClient::GetCaps(TDes8& aDes) const +// Return the IicClient capabilities. + { + TPckgBuf b; + b().version = TVersion(KIicClientMajorVersionNumber, KIicClientMinorVersionNumber, KIicClientBuildVersionNumber); + Kern::InfoCopy(aDes, b); + } + +// Create a channel on the device. +TInt DDeviceIicClient::Create(DLogicalChannelBase*& aChannel) + { + __KTRACE(Kern::Printf("DDeviceIicClient::Create(DLogicalChannelBase*& aChannel)")); + + if (iOpenChannels >= KMaxNumChannels) + { + return KErrOverflow; + } + aChannel = new DChannelIicClient; + return aChannel ? KErrNone : KErrNoMemory; + } + +DChannelIicClient::DChannelIicClient() + { + iClient = &Kern::CurrentThread(); + iSlaveCallback = NULL; + // Increase the DThread's ref count so that it does not close without us + iClient->Open(); + } + +DChannelIicClient::~DChannelIicClient() + { + __KTRACE(Kern::Printf("DChannelIicClient::~DChannelIicClient()")); + iDfcQue->Destroy(); + + //free memory: + delete iSpiHeader; +#ifdef STANDALONE_CHANNEL +#ifdef MASTER_MODE + if(iMasterChannel) + delete iMasterChannel; +#endif/*MASTER_MODE*/ + +#ifdef SLAVE_MODE + if(iSlaveChannel) + delete iSlaveChannel; +#endif/*SLAVE_MODE*/ +#endif + + // decrement the DThread's reference count + Kern::SafeClose((DObject*&) iClient, NULL); + } + +TInt DChannelIicClient::DoCreate(TInt aUnit, const TDesC8* /*aInfo*/, + const TVersion& /*aVer*/) + { + __KTRACE(Kern::Printf("DChannelIicClient::DoCreate(), UNIT %d", aUnit)); + TInt r = KErrNone; + + // Bus Realisation Config iCsiBusId; + iCsiBusId = 0; + SET_BUS_TYPE(iCsiBusId,DIicBusChannel::ESpi); + SET_CHAN_NUM(iCsiBusId,KCodecChannelNumber); + SET_SLAVE_ADDR(iCsiBusId,14); + +#ifdef STANDALONE_CHANNEL +#ifdef MASTER_MODE + // create channel 0 - as master.. + iMasterChannel = DCsiChannelMaster::New(0, DIicBusChannel::ESpi, DIicBusChannel::EFullDuplex); + if (!iMasterChannel) + { + __KTRACE_OPT(KIIC, Kern::Printf("Error no memory")); + return KErrNoMemory; + } +#endif /*MASTER_MODE*/ + +#ifdef SLAVE_MODE + // and created channel 1 - as slave.. + iSlaveChannel = DCsiChannelSlave::New(1, DIicBusChannel::ESpi, DIicBusChannel::EFullDuplex); + if (!iSlaveChannel) + { + __KTRACE_OPT(KIIC, Kern::Printf("Error no memory")); + #ifdef MASTER_MODE + delete iMasterChannel; //Free memory + #endif + return KErrNoMemory; + } +#endif /*SLAVE_MODE*/ + + +#endif/*STANDALONE_CHANNEL*/ + + r = Kern::DynamicDfcQCreate(iDfcQue, KIicClientThreadPriority, KIicClientThreadName); + if(r == KErrNone) + { + iSpiHeader = new TConfigSpiBufV01(DefaultHeader); + if(iSpiHeader) + { + SetDfcQ(iDfcQue); + iMsgQ.Receive(); + } + else + { + r = KErrNoMemory; + } + } + return r; + } + +void DChannelIicClient::HandleMsg(TMessageBase* aMsg) + { + TThreadMessage& m = *(TThreadMessage*) aMsg; + TInt id = m.iValue; + + if (id == ECloseMsg) + { + // make sure, we've released the SlaveChannel on closure.. + DoControl(RBusCsiTestClient::EReleaseSlaveChannel, NULL, NULL); + + iMsgQ.iMessage->Complete(KErrNone, EFalse); + return; + } + else if (id == KMaxTInt) + { + DoCancel(m.Int0()); + m.Complete(KErrNone, ETrue); + return; + } + + if (id < 0) + { + TRequestStatus* pS = (TRequestStatus*) m.Ptr0(); + TInt r = DoRequest(~id, pS, m.Ptr1(), m.Ptr2()); + if (r != KErrNone) + { + Kern::RequestComplete(iClient, pS, r); + } + m.Complete(KErrNone, ETrue); + } + else + { + TInt r = DoControl(id, m.Ptr0(), m.Ptr1()); + m.Complete(r, ETrue); + } + } + +void DChannelIicClient::DoCancel(TInt aMask) + { + // Cancel an outstanding request. + // Not implemented. + return; + } + +#ifdef MASTER_MODE +TInt DChannelIicClient::QueueTransaction(TInt aBusId, TIicBusTransaction* aTransaction, TIicBusCallback *aCallback/*=NULL*/) + { +#ifndef STANDALONE_CHANNEL + if(!aCallback) + return IicBus::QueueTransaction(aBusId, aTransaction); + else + return IicBus::QueueTransaction(aBusId, aTransaction, aCallback); +#else + if(iMasterChannel) + { + aTransaction->iBusId = aBusId; + if(!aCallback) + return iMasterChannel->QueueTransaction(aTransaction); + else + return iMasterChannel->QueueTransaction(aTransaction, aCallback); + } + else + return KErrGeneral; //iMaster not initialised? - channels not created? +#endif + } +#endif /*MASTER_MODE*/ + +#ifdef SLAVE_MODE +TInt DChannelIicClient::RegisterRxBuffer(TInt aChannelId, TPtr8 aRxBuffer, TInt8 aBufGranularity, TInt8 aNumWords, TInt8 aOffset) + { +#ifdef STANDALONE_CHANNEL + if(iSlaveChannel) + return iSlaveChannel->RegisterTxBuffer(aRxBuffer, aBufGranularity, aNumWords, aOffset); + else + return KErrGeneral; +#else + return IicBus::RegisterRxBuffer(aChannelId, aRxBuffer, aBufGranularity, aNumWords, aOffset); +#endif + } + +TInt DChannelIicClient::RegisterTxBuffer(TInt aChannelId, TPtr8 aRxBuffer, TInt8 aBufGranularity, TInt8 aNumWords, TInt8 aOffset) + { +#ifdef STANDALONE_CHANNEL + if(iSlaveChannel) + return iSlaveChannel->RegisterTxBuffer(aRxBuffer, aBufGranularity, aNumWords, aOffset); + else + return KErrGeneral; +#else + return IicBus::RegisterTxBuffer(aChannelId, aRxBuffer, aBufGranularity, aNumWords, aOffset); +#endif + } + +TInt DChannelIicClient::CaptureChannel(TInt aBusId, TDes8* aConfigHdr, TIicBusSlaveCallback* aCallback, TInt& aChannelId, TBool aAsynch) + { +#ifdef STANDALONE_CHANNEL + if(iSlaveChannel) + return iSlaveChannel->CaptureChannel(aConfigHdr, aCallback, aChannelId, aAsynch); + else + return KErrGeneral; +#else + return IicBus::CaptureChannel(aBusId, aConfigHdr, aCallback, aChannelId, aAsynch); +#endif + } + + +TInt DChannelIicClient::ReleaseChannel(TInt aChannelId) + { +#ifdef STANDALONE_CHANNEL + if(iSlaveChannel) + return iSlaveChannel->ReleaseChannel(); + else + return KErrGeneral; +#else + return IicBus::ReleaseChannel(aChannelId); +#endif + } + +TInt DChannelIicClient::SetNotificationTrigger(TInt aChannelId, TInt aTrigger) + { +#ifdef STANDALONE_CHANNEL + if(iSlaveChannel) + return iSlaveChannel->SetNotificationTrigger(aTrigger); + else + return KErrGeneral; +#else + return IicBus::SetNotificationTrigger(aChannelId, aTrigger); +#endif + } +#endif /*SLAVE_MODE*/ + +// This test tests the timeout for the half-duplex Write requests. +// it creates a transaction with one transfer. +// Clk 200kHz actually sets the clock to 260000 kHz. With 8bit granularity - gives 25kB/s +// 32,5 bytes should be transferred in 1ms +// so e.g. setting the timeout to 1ms and the transfer size to more than that 32 bytes should +// cause a transfer timeout for transmission. +// test case: +// 1. setting timeout to 1ms with buffer 128 bytes - should result in KErrTImeout return value. +// 2. setting timeout to 5ms (~160 bytes transfer) - should result in KErrNone return value. +#ifdef MASTER_MODE +TInt DChannelIicClient::TestTransferTimeout() + { + __KTRACE(Kern::Printf("DChannelIicClient::TestTransferTimeout()")); + TInt r = KErrNone; + + TUint32 busId = 0; + SET_BUS_TYPE(busId,DIicBusChannel::ESpi); + SET_CHAN_NUM(busId,0); + SET_SLAVE_ADDR(busId,13); // test it with any number between 1-32 + + // Create a transaction header + const TConfigSpiV01 TestHeader = + { + ESpiWordWidth_8, //iWordWidth + 260000, //iClkSpeed + ESpiPolarityLowRisingEdge, //iClkMode + 1, // iTimeoutPeriod + EBigEndian, // iEndianness + EMsbFirst, //iBitOrder + 0, //iTransactionWaitCycles + ESpiCSPinActiveLow //iCsPinActiveMode + }; + + TPckgBuf header(TestHeader); + + // create transfer object + TBuf8<128> transfer_buf; // buffer.. + transfer_buf.SetLength(transfer_buf.MaxLength()); + + TIicBusTransfer transfer(TIicBusTransfer::EMasterWrite, 8, &transfer_buf); + + // Create a transaction using header and transfer.. + TIicBusTransaction transaction1(&header, &transfer); + + // this transaction should return KErrTimeout + r = QueueTransaction(busId, &transaction1); + + if (r != KErrTimedOut) + { + __KTRACE(Kern::Printf("no timeout??, r= %d", r)); + return r; + } + + // change the timeout to and create another transaction.. + header().iTimeoutPeriod = 6; // it works for 4 too (~130Bytes) + transfer_buf.SetLength(transfer_buf.MaxLength()); + TIicBusTransfer transfer2(TIicBusTransfer::EMasterWrite, 8, &transfer_buf); + + TIicBusTransaction transaction2(&header, &transfer2); + + // this transaction should return KErrNone + r = QueueTransaction(busId, &transaction2); + + if (r != KErrNone) + { + __KTRACE(Kern::Printf("Transaction failed, r= %d", r)); + } + + return r; + } + +TInt DChannelIicClient::TestHalfDuplexTransaction() + { + __KTRACE(Kern::Printf("DChannelIicClient::TestHalfDuplexTransaction()")); + TInt r = KErrNone; + + TUint32 busId = 0; + SET_BUS_TYPE(busId,DIicBusChannel::ESpi); + SET_CHAN_NUM(busId,0); + SET_SLAVE_ADDR(busId,13); // test it with any number between 1-32 + + // create header + const TConfigSpiV01 TestHeader = + { + ESpiWordWidth_8, //iWordWidth + 260000, //iClkSpeed + ESpiPolarityLowRisingEdge, //iClkMode + 500, // iTimeoutPeriod + EBigEndian, // iEndianness + EMsbFirst, //iBitOrder + 0, //iTransactionWaitCycles + ESpiCSPinActiveLow //iCsPinActiveMode + }; + + TPckgBuf header(TestHeader); + + // create transfer object + TBuf8<32> txTransferBuf; // buffer.. + TBuf8<32> rxTransferBuf; // buffer.. + for (TInt i = 0; i < txTransferBuf.MaxLength(); ++i) + { + txTransferBuf.Append(i); + } + txTransferBuf.SetLength(txTransferBuf.MaxLength()); + rxTransferBuf.SetLength(rxTransferBuf.MaxLength()); + + // combine some transfers -in one transaction. + TIicBusTransfer txTransfer(TIicBusTransfer::EMasterWrite, 8, &txTransferBuf); + TIicBusTransfer rxTransfer(TIicBusTransfer::EMasterRead, 8, &rxTransferBuf); + txTransfer.LinkAfter(&rxTransfer); + + TIicBusTransfer txTransfer2(TIicBusTransfer::EMasterWrite, 8, &txTransferBuf); + rxTransfer.LinkAfter(&txTransfer2); + + TIicBusTransfer rxTransfer2(TIicBusTransfer::EMasterRead, 8, &rxTransferBuf); + txTransfer2.LinkAfter(&rxTransfer2); + + // Create a transaction using header and list of transfers.. + TIicBusTransaction transaction(&header, &txTransfer); + + // queue the transaction - it should complete successful + r = QueueTransaction(busId, &transaction); + + return r; + } + +TInt DChannelIicClient::TestBulkTransfer() + { + //Create a Transaction object which contains 2 Transfers. of buffer sizes say 256 and 64 + const TUint8 KTrBuf1Length = 128; + const TUint8 KTrBuf2Length = 64; + + TUint32 busId = 0; + SET_BUS_TYPE(busId,DIicBusChannel::ESpi); + SET_CHAN_NUM(busId,0); + SET_SLAVE_ADDR(busId,5); + + // create header + const TConfigSpiV01 TestHeader = + { + ESpiWordWidth_16, //iWordWidth + 260000, //iClkSpeed + ESpiPolarityLowRisingEdge, //iClkMode + 3000, // iTimeoutPeriod + EBigEndian, // iEndianness + EMsbFirst, //iBitOrder + 0, //iTransactionWaitCycles + ESpiCSPinActiveLow //iCsPinActiveMode + }; + + TPckgBuf header(TestHeader); + + TBuf8 transBuf1; + TBuf8 transBuf2; + TInt r = KErrNone; + + for (TInt i = 0; i < KTrBuf1Length; ++i) + { + transBuf1.Append(i + '0'); + } + + for (TInt i = 0; i < KTrBuf2Length; ++i) + { + transBuf2.Append(i + 'a'); + } + + transBuf1.SetLength(KTrBuf1Length); + transBuf2.SetLength(KTrBuf2Length); + + //TIicBusTransfer trans1; + TIicBusTransfer trans1(TIicBusTransfer::TIicBusTransfer::EMasterWrite, 8, &transBuf2); + TIicBusTransfer trans2(TIicBusTransfer::TIicBusTransfer::EMasterRead, 8, &transBuf1); + trans1.LinkAfter(&trans2); + + // for the other direction - re-use buffers..(they will be interleaved) + TIicBusTransfer trans3(TIicBusTransfer::TIicBusTransfer::EMasterRead, 8, &transBuf1); + TIicBusTransfer trans4(TIicBusTransfer::TIicBusTransfer::EMasterWrite, 8, &transBuf2); + trans3.LinkAfter(&trans4); + + // transaction + TIicBusTransaction trans(&header, &trans1); // this will set the transaction with trans1 and trans2 + trans.SetFullDuplexTrans(&trans3); // and this will add trans3 and trans4 for the other direction + + r = QueueTransaction(busId, &trans); + + return r; + } + +// Testing CSI interface with AudioCodec: +// this involves several CSI write transactions to set-up the AudioCodec +// and configure it to generate the sound (of a particular frequency) + +// CSI configuration parameters needed to transmit data to the Codec +// these are used as the transaction header object. +const TConfigSpiV01 KCodecSpiV01Config = + { + ESpiWordWidth_8, //iWordWidth + 260000, //iClkSpeed + ESpiPolarityHighFallingEdge, //iClkMode + 100, // iTimeoutPeriod + EBigEndian, // iEndianness + EMsbFirst, //iBitOrder + 0, //iTransactionWaitCycles + ESpiCSPinActiveLow //iCsPinActiveMode + }; + +// helper function - to update buffer data and queue the transaction with the updated data +TInt DChannelIicClient::QueueRegisterWriteTransaction(TInt16 aRegister, + TInt16 aValue, TIicBusTransaction* aTrans, TInt aConfig) + { + iTransBuff().iRegister = aRegister; + iTransBuff().iData = aValue; + TInt r = QueueTransaction(aConfig, aTrans); + return r; + } + +// this method configures the codec and sets its registers to create a sound of +// requested frequency, duration time, volume and the time..etc.. +// to set these params we will be using single transactions - reusing all objects created on the stack: +// - transaction (TIicBusTransaction), +// - header object (TConfigSpiV01 - embedded in TPckgBuf headerBuff) +// - TIicBusRealisationConfig - busId / config + +TInt DChannelIicClient::TestAudioCodecBeep(TUint8 aFreq, TUint8 aTime, + TUint8 aOffTime, TUint8 aVolume, TBool aRepeat /*=0*/) + { + __KTRACE(Kern::Printf("DChannelIicClient::TestAudioCodecBeep()")); + + // enable and configure pin 25 - it is connected to the chip's reset line + GPIO::SetPinMode(KCodecResetPin, GPIO::EEnabled); + GPIO::SetPinDirection(KCodecResetPin, GPIO::EOutput); + GPIO::SetDebounceTime(KCodecResetPin, 0); + + // Bus Realisation Config + TUint32 iCsiBusId = 0; + SET_BUS_TYPE(iCsiBusId,DIicBusChannel::ESpi); + SET_CHAN_NUM(iCsiBusId,KCodecChannelNumber); + SET_SLAVE_ADDR(iCsiBusId,KCodecCSPin); // use codec's CS pin number as a Slave address + + TInt config = iCsiBusId; + + // create header + TPckgBuf header(KCodecSpiV01Config); + + // create transfer object - use iTransBuff member, which contains RCS42AudioCodec::TCodecConfigData + TIicBusTransfer transfer(TIicBusTransfer::EMasterWrite, 8, &iTransBuff); + TIicBusTransaction transaction(&header, &transfer); + + // setup the transaction - to use this header and transfer object + transaction.SetHalfDuplexTrans(&header, &transfer); + + // fill the TCodecConfigData.Address only once, it won't change.. + iTransBuff().iAddress = KCodecWriteCommand; + + // power-up sequence.. + // put !reset line high to start the power-up sequence.. + // GPIO::SetOutputState(KCodecResetPin, GPIO::ELow); + GPIO::SetOutputState(KCodecResetPin, GPIO::EHigh); + + TInt r = KErrNone; + + r = QueueRegisterWriteTransaction(KHwCS42L51PwrCtrl, KHtCS42L51PwrCtrl_PDN, &transaction, config); + CHECK_ERR(r); + + r = QueueRegisterWriteTransaction(KHwCS42L51PwrCtrl, KHtCS42L51PwrCtrl_PDN_ALL, &transaction, config); + CHECK_ERR(r); + + // freeze all registers.. until are set-up. + r = QueueRegisterWriteTransaction(KHwCS42L51DACControl, KHtCS42L51DACControl_FREEZE, &transaction, config); + CHECK_ERR(r); + + //Set Mic power control and speed control register(0x03) + r = QueueRegisterWriteTransaction(KHwCS42L51MicPwrSpeed, KHtCS42L51MicPwrSpeed_AUTO, &transaction, config); + CHECK_ERR(r); + + // interface control (0x04) // serial port settings.. + // I2s, Slave, SDOUT->SDIN internally connected.. Digimix->ON? + // use I2S format, Slave, Digital & Mic mix + TUint16 val = (KHCS42L51CtrlI2sUpto24bit << KHsCS42L51CtrlFormat) + | KHtCS42L51Ctrl_DIGMIX | KHtCS42L51Ctrl_MICMIX; + r = QueueRegisterWriteTransaction(KHwCS42L51Ctrl, val, &transaction, config); + CHECK_ERR(r); + + // DAC output select (0x08) + // 7 6 5 4 3 2 1 0 + // HP_GAIN2 HP_GAIN1 HP_GAIN0 DAC_SNGVOL INV_PCMB INV_PCMA DACB_MUTE DACA_MUTE + r = QueueRegisterWriteTransaction(KHwCS42L51DACOutputControl, KHtCS42L51DACOutputControl_DAC_SNGVOL, &transaction, config); + CHECK_ERR(r); + + // ALCX & PGAX ctrl, A(0x0A), B (0x0B) + r = QueueRegisterWriteTransaction(KHwCS42L51ALC_PGA_A_Control, 0, &transaction, config); + CHECK_ERR(r); + r = QueueRegisterWriteTransaction(KHwCS42L51ALC_PGA_B_Control, 0, &transaction, config); + CHECK_ERR(r); + + // ADCx Mixer Volume Ctrl A(0x0E), B (0x0F) + r = QueueRegisterWriteTransaction(KHwCS42L51ALC_ADC_A_MixVolume, 0x10, &transaction, config); + CHECK_ERR(r); + + r = QueueRegisterWriteTransaction(KHwCS42L51ALC_ADC_B_MixVolume, 0x10, &transaction, config); + CHECK_ERR(r); + + // PCMx Volume Ctrl A(0x10), B (0x11) + r = QueueRegisterWriteTransaction(KHwCS42L51ALC_PCM_A_MixVolume, 0x10, &transaction, config); + CHECK_ERR(r); + r = QueueRegisterWriteTransaction(KHwCS42L51ALC_PCM_B_MixVolume, 0x10, &transaction, config); + CHECK_ERR(r); + + // Volume Control: AOUTA (Address 16h) & AOUTB (Address 17h) + //send next one.. + r = QueueRegisterWriteTransaction(KHwCS42L51ALC_Out_A_Volume, 0x10, &transaction, config); + CHECK_ERR(r); + r = QueueRegisterWriteTransaction(KHwCS42L51ALC_Out_B_Volume, 0x10, &transaction, config); + CHECK_ERR(r); + + // DAC Control (Address 09h) + // 7 6 5 4 3 2 1 0 + // DATA_SEL1 DATA_SEL0 FREEZE Reserved DEEMPH AMUTE DAC_SZC1 DAC_SZC0 + // DATA_SEL1 DATA_SEL0: + // 00 - PCM Serial Port to DAC + // 01 - Signal Processing Engine to DAC + // 10 - ADC Serial Port to DAC (11 - Reserved) + r = QueueRegisterWriteTransaction(KHwCS42L51DACControl, (1 << KHsCS42L51DACControl_DATA_SEL), &transaction, config); + CHECK_ERR(r); + + // power-up sequence..end - clear PDN ..after loading register settings.. + r = QueueRegisterWriteTransaction(KHwCS42L51PwrCtrl, 0, &transaction, config); + CHECK_ERR(r); + + // now - the codec is ready to generate the beep of requested frequency.. + // Set the beep frequency and time.. + r = QueueRegisterWriteTransaction(KHwCS42L51ALC_Beep_FQ_Time, (aFreq + << KHsCS42L51ALC_Beep_FQ) | (aTime & KHmCS42L51ALC_Beep_Time_Mask), &transaction, config); + CHECK_ERR(r); + + // Set the Volume and off time + r = QueueRegisterWriteTransaction(KHwCS42L51ALC_Beep_Off_Volume, + (aOffTime << KHsCS42L51ALC_Beep_Off) | (aVolume & KHmCS42L51ALC_Beep_Volume_Mask), + &transaction, config); + CHECK_ERR(r); + + // set the 'repeat' bit and enable the beep.. + r = QueueRegisterWriteTransaction(KHwCS42L51ALC_Beep_Conf_Tone, + (aRepeat ? KHtCS42L51ALC_Beep_Conf_Tone_REPEAT : 0) | + KHtCS42L51ALC_Beep_Conf_Tone_BEEP, &transaction, config); + CHECK_ERR(r); + + NKern::Sleep(500); // give it some time to play ;) + + // power down the codec: + r = QueueRegisterWriteTransaction(KHwCS42L51PwrCtrl, KHtCS42L51PwrCtrl_PDN, &transaction, config); + CHECK_ERR(r); + + GPIO::SetOutputState(KCodecResetPin, GPIO::ELow); + return KErrNone; + } + + +// Test Transaction with different configuration settings +// 1) Different Header settinngs (TConfigSpiBufV01)) +// 2) Different Bus Config settings (Bus Realisation Config) +TInt DChannelIicClient::TestConfigParams(TInt aBusId) + { + TInt r = KErrNone; + + const TUint8 KTrasferBufferLength = 120; + + //First Create a Half Duplex Transfer List of 3 Transfers of Type W,R,W + TBuf8 trBuf1; + TBuf8 trBuf2; + + TIicBusTransfer hdTrasfer1(TIicBusTransfer::EMasterWrite, 8, &trBuf1); + TIicBusTransfer hdTrasfer2(TIicBusTransfer::EMasterRead, 8, &trBuf2); + + //Link the Half Duplex Transfers 1->2 + hdTrasfer1.LinkAfter(&hdTrasfer2); + + //Create A Ful Duplex Transfer of 3 Transfers of type ,R,W,R + TBuf8 trBuf3; + TBuf8 trBuf4; + + TIicBusTransfer fdTrasfer1(TIicBusTransfer::EMasterRead, 8, &trBuf3); + TIicBusTransfer fdTrasfer2(TIicBusTransfer::EMasterWrite, 8, &trBuf4); + + //Link the Full Duplex Transfers 1->2 + fdTrasfer1.LinkAfter(&fdTrasfer2); + + for (TUint i = 0; i < KTrasferBufferLength; i++) + { + //Fill the Buffers associated with Write Transfer with some data + trBuf1.Append(i + '0'); + trBuf4.Append(i + 'A'); + } + + trBuf1.SetLength(KTrasferBufferLength); + trBuf2.SetLength(KTrasferBufferLength); + trBuf3.SetLength(KTrasferBufferLength); + trBuf4.SetLength(KTrasferBufferLength); + + // Create a transaction using header and transfer.. + TIicBusTransaction fdTransaction(iSpiHeader, &hdTrasfer1); + + fdTransaction.SetFullDuplexTrans(&fdTrasfer1); + + // Queue Transaction + r = QueueTransaction(aBusId, &fdTransaction); + + return r; + } + + +// Test Duplex Transaction +// Construct two chain of combined transfers for the transaction: +// 1) A Half Duplex Transfer with a Read , Write and Read operation +// 2) A Full Duplex Transfer with a Write, Read and Write Operation. +TInt DChannelIicClient::TestDuplexTransaction() + { + __KTRACE(Kern::Printf("DChannelIicClient::TestDuplexTransaction\n")); + + TInt r = KErrNone; + + TUint32 busId = 0; + SET_BUS_TYPE(busId,DIicBusChannel::ESpi); + SET_CHAN_NUM(busId,0); + SET_SLAVE_ADDR(busId,1); + + // create header + const TConfigSpiV01 DefaultHeader = + { + ESpiWordWidth_8, //iWordWidth + 260000, //iClkSpeed + ESpiPolarityLowRisingEdge, //iClkMode + 1000, // iTimeoutPeriod + EBigEndian, // iEndianness + EMsbFirst, //iBitOrder + 0, //iTransactionWaitCycles + ESpiCSPinActiveLow//iCsPinActiveMode + }; + + const TUint8 KTrasferBufferLength = 120; + + TConfigSpiBufV01 header(DefaultHeader); + + //First Create a Half Duplex Transfer List of 3 Transfers of Type W,R,W + TBuf8 trBuf1; + TBuf8 trBuf2; + TBuf8 trBuf3; + + TIicBusTransfer hdTrasfer1(TIicBusTransfer::EMasterWrite, 8, &trBuf1); + TIicBusTransfer hdTrasfer2(TIicBusTransfer::EMasterRead, 8, &trBuf2); + TIicBusTransfer hdTrasfer3(TIicBusTransfer::EMasterWrite, 8, &trBuf3); + + //Link the Half Duples Transfers 1->2->3 + hdTrasfer1.LinkAfter(&hdTrasfer2); + hdTrasfer2.LinkAfter(&hdTrasfer3); + + //Create A Ful Duples Transfer of 3 Transfers of type ,R,W,R + TBuf8 trBuf4; + TBuf8 trBuf5; + TBuf8 trBuf6; + + TIicBusTransfer fdTrasfer1(TIicBusTransfer::EMasterRead, 8, &trBuf4); + TIicBusTransfer fdTrasfer2(TIicBusTransfer::EMasterWrite, 8, &trBuf5); + TIicBusTransfer fdTrasfer3(TIicBusTransfer::EMasterRead, 8, &trBuf6); + + //Link the Full Duples Transfers 1->2->3 + fdTrasfer1.LinkAfter(&fdTrasfer2); + fdTrasfer2.LinkAfter(&fdTrasfer3); + + for (TUint i = 0; i < KTrasferBufferLength; i++) + { + //Fill the Buffers associated with Write Transfer with some data + trBuf1.Append(i + '0'); + trBuf3.Append(i + 'A'); + trBuf5.Append(i + 'a'); + //Read Buffers + trBuf2.Append('$'); + trBuf4.Append('?'); + trBuf6.Append('*'); + } + + trBuf1.SetLength(KTrasferBufferLength); + trBuf2.SetLength(KTrasferBufferLength); + trBuf3.SetLength(KTrasferBufferLength); + trBuf4.SetLength(KTrasferBufferLength); + trBuf5.SetLength(KTrasferBufferLength); + trBuf6.SetLength(KTrasferBufferLength); + + // Create a transaction using header and transfer.. + TIicBusTransaction fdTransaction(&header, &hdTrasfer1); + fdTransaction.SetFullDuplexTrans(&fdTrasfer1); + + //Queue Transaction + r = QueueTransaction(busId, &fdTransaction); + + return r; + } + +// Callback for Master's asynchronous transactions +// this is called whenever the transaction has been finished. +void DChannelIicClient::AsyncTransCallbackFunc(TIicBusTransaction* aTransaction, TInt /*aBusId*/, TInt aResult, TAny* aParam) + { + __KTRACE(Kern::Printf("DChannelIicClient::AsyncTransCallbackFunc aResult =%d\n",aResult)); + TCallBckRequest<3> *cr = (TCallBckRequest<3>*)aParam; + + // complete request.. + Kern::RequestComplete(cr->iClient, cr->iReqStatus, aResult); + + // now can finally delete cr object = wchich will delete 1-6 (i don't like that..TIicBusTransaction has all this info..) + delete cr; + if(aTransaction) + delete aTransaction; + } + +/* +Test Asynchronous Transaction +with a chain of HD(HalfDuplex) transfers: Read -> Write -> Read + + Memory management for asynchronous transactions: we create the following on the heap: + 1. transaction header (in DoRequest), + 2. transaction + 3. transfers for transaction (chained in linked-list) + 4. buffers for transfers + 5. IIC callback object (TIicBusCallback) + 6. callback request - which stores pointers to callback object(TIicBusCallback), + and pointers to the client and the request status object (used by RequestComplete) + + All of these need to be deleted in the AsyncTransCallbackFunc + (at the end of transaction) +*/ +const TUint8 KTrasferBufferLength = 120; + +TInt DChannelIicClient::TestAsynTransaction(TRequestStatus* aStatus, TConfigSpiBufV01* aSpiHeader, TInt aBusId) + { + __KTRACE(Kern::Printf("DChannelIicClient::TestAsynTransaction\n")); + TInt r = KErrNone; + + // Store required RequestComplete pointers in our TCbRequest (6.) + TCallBckRequest<3> *cbRequest = new TCallBckRequest<3>(iClient, aStatus, aSpiHeader); + + //Create the CallBack Function (5.) + TIicBusCallback *callback = new TIicBusCallback(AsyncTransCallbackFunc, (TAny*)cbRequest, iDfcQue, 5); // 5 arbitrary + cbRequest->iCallback = callback; + + // create buffers (4.) + HBuf8* trBuf1 = HBuf8::New(KTrasferBufferLength); + cbRequest->iBuffers[0] = trBuf1; + HBuf8* trBuf2 = HBuf8::New(KTrasferBufferLength); + cbRequest->iBuffers[1] = trBuf2; + HBuf8* trBuf3 = HBuf8::New(KTrasferBufferLength); + cbRequest->iBuffers[2] = trBuf3; + + // create transfers..(3.) + TIicBusTransfer* hdTrasfer1 = new TIicBusTransfer(TIicBusTransfer::EMasterRead, 8, trBuf1); + cbRequest->iTransfers[0] = hdTrasfer1; + TIicBusTransfer* hdTrasfer2 = new TIicBusTransfer(TIicBusTransfer::EMasterWrite, 8, trBuf2); + cbRequest->iTransfers[1] = hdTrasfer2; + TIicBusTransfer* hdTrasfer3 = new TIicBusTransfer(TIicBusTransfer::EMasterRead, 8, trBuf3); + cbRequest->iTransfers[2] = hdTrasfer3; + + // Create a transaction using header and transfer..(2.) + TIicBusTransaction* transaction = new TIicBusTransaction(aSpiHeader, hdTrasfer1); + + if(!trBuf1 || !trBuf2 || !trBuf2 || + !hdTrasfer1 || !hdTrasfer2 || !hdTrasfer3 || + !transaction || ! cbRequest || !callback) + { + delete cbRequest; + __KTRACE(Kern::Printf("No memory for allocating transfer buffers")); + return KErrNoMemory; + } + + + // put some dummy data in buffers.. + for (TUint i = 0; i < KTrasferBufferLength; ++i) + { + //Fill the Buffers associated with Write Transfer with some data + trBuf1->Append(i + '0'); + trBuf2->Append(i + 'a'); + trBuf3->Append(i + 'A'); + } + + //Link the transfers 1->2->3 + hdTrasfer1->LinkAfter(hdTrasfer2); + hdTrasfer2->LinkAfter(hdTrasfer3); + + // Queue Transaction + r = QueueTransaction(aBusId, transaction, callback); + return r; + } +#endif/*MASTER_MODE*/ + +// ======================= +// Slave channel tests +// +// callbackForOneduplex asynchronous transaction.. +void DChannelIicClient::MasterCallbackFunc(TIicBusTransaction* aTransction, + TInt aBusId, + TInt aResult, + TAny* aParam) + { +// DChannelIicClient* a = (DChannelIicClient*) aParam; + __KTRACE(Kern::Printf("MasterCallbackFunc, aResult = %d", aResult)); + } + +#ifdef MASTER_MODE +// this method asynchronously queues one duplex transaction using +// the buffers, which are part of the DChannelIicClient(). +TInt DChannelIicClient::QueueOneDuplexTransaction(TInt aSize) + { + __KTRACE(Kern::Printf("QueueOneDuplexTransaction, aSize = %d", aSize)); + + TInt r = KErrNone; + if(aSize > KMaxSlaveTestBufferSize) + { + return KErrArgument; + } + + TUint32 busId = 0; + SET_BUS_TYPE(busId,DIicBusChannel::ESpi); + SET_CHAN_NUM(busId,0); + SET_SLAVE_ADDR(busId,13); // test it with any number between 1-32 + + // create header + const TConfigSpiV01 TestHeader = + { + ESpiWordWidth_8, //iWordWidth + 260000, //iClkSpeed + ESpiPolarityLowRisingEdge, //iClkMode + 500, // iTimeoutPeriod + EBigEndian, // iEndianness + EMsbFirst, //iBitOrder + 0, //iTransactionWaitCycles + ESpiCSPinActiveLow //iCsPinActiveMode + }; + TPckgBuf header(TestHeader); + + TBuf8 txBuf; // buffer.. + TBuf8 rxBuf; // buffer.. + + // create transfer object + for (TInt i = 0; i < aSize; ++i) + { + txBuf.Append(i); + } + rxBuf.SetLength(aSize); + + // combine some transfers -in one transaction. + TIicBusTransfer txTransfer(TIicBusTransfer::EMasterWrite, 8, &txBuf); + TIicBusTransfer rxTransfer(TIicBusTransfer::EMasterRead, 8, &rxBuf); + + // Create a transaction using header and list of transfers.. + iMasterTransaction.SetHalfDuplexTrans(&header, &txTransfer); + iMasterTransaction.SetFullDuplexTrans(&rxTransfer); + + // queue the transaction + r = QueueTransaction(busId, &iMasterTransaction); + + return r; + } +#endif /*MASTER_MODE*/ + +#ifdef SLAVE_MODE +TInt DChannelIicClient::RegisterSlaveBuffers() + { + __KTRACE(Kern::Printf("RegisterSlaveBuffers(), size %d", iSlaveBufSize)); + TInt r = KErrNone; + // put some data in the buffer - so we could see-if this is actually beeing transfered... + for(TInt i = 0; i < iSlaveBufSize; ++i) + { + iTxBuf.Append(i); + } + + TPtr8 rxBuf(0, 0); + TPtr8 txBuf(0, 0); + + rxBuf.Set((TUint8*) iRxBuf.Ptr(), iSlaveBufSize, iRxBuf.MaxLength()); + txBuf.Set((TUint8*) iTxBuf.Ptr(), iSlaveBufSize, iTxBuf.MaxLength()); + + r = RegisterRxBuffer(iChannelId, rxBuf, 8, iSlaveBufSize, 0); + + if(r != KErrNone) + { + __KTRACE(Kern::Printf("Error Register Rx Buffer, r %d", r)); + } + else + { + r = RegisterTxBuffer(iChannelId, txBuf, 8, iSlaveBufSize, 0); + } + + return r; + } + +TInt DChannelIicClient::CaptureSlaveChannel(TInt aBufSize, TBool aAsynch /* = EFalse*/) + { + if(aBufSize > KMaxSlaveTestBufferSize) + { + return KErrArgument; + } + + TInt r = KErrNone; + TUint32 slaveBusId = 0; + SET_BUS_TYPE(slaveBusId,DIicBusChannel::ESpi); + SET_CHAN_NUM(slaveBusId,1); + + // create header + const TConfigSpiV01 TestHeader = + { + ESpiWordWidth_8, //iWordWidth + 260000, //iClkSpeed + ESpiPolarityLowRisingEdge, //iClkMode + 500, // iTimeoutPeriod + EBigEndian, // iEndianness + EMsbFirst, //iBitOrder + 0, //iTransactionWaitCycles + ESpiCSPinActiveLow //iCsPinActiveMode + }; + + TPckgBuf header(TestHeader); + + // create callback objects for slave tests.. + if (!iSlaveCallback) + { + iSlaveCallback = new TIicBusSlaveCallback(SlaveCallbackFunc, (TAny*) this, iDfcQue, 0); + } + + if (!iMasterCallback) + { + iMasterCallback = new TIicBusCallback(MasterCallbackFunc, (TAny*) this, iDfcQue, 0); + } + + if (!(iSlaveCallback && iMasterCallback)) + { + if(iSlaveCallback) + { + delete iSlaveCallback; + } + + if(iMasterCallback) + { + delete iMasterCallback; + } + return KErrNoMemory; + } + + TInt channelId = 0; + // capture channel.. + r = CaptureChannel(slaveBusId, &header, iSlaveCallback, channelId, aAsynch); + if (r != KErrNone) + { + __KTRACE(Kern::Printf("Error capturing the channel, r %d", r)); + } + else + { + iSlaveBufSize = aBufSize; + + if(!aAsynch) + { + iChannelId = channelId; + __KTRACE(Kern::Printf("channelId %d", iChannelId)); + r = RegisterSlaveBuffers(); + } + } + + return r; + } + +TInt DChannelIicClient::ReleaseSlaveChannel() + { + TInt r = KErrNone; + // release the channel + + if (iChannelId) + { + r = ReleaseChannel(iChannelId); + if (r == KErrNone) + { + iChannelId = 0; + if(iSlaveCallback) + { + delete iSlaveCallback; + iSlaveCallback = NULL; + } + + if(iMasterCallback) + { + delete iMasterCallback; + iMasterCallback = NULL; + } + } + else + { + __KTRACE(Kern::Printf("Error releasing the channel, r %d", r)); + } + } + // else // if the channel was released already - silently return KErrNone.. + + return r; + } + +#ifdef _DEBUG +void PrintTrigger(TInt aTrigger) + { + Kern::Printf("\naReturn:"); + if(aTrigger & ETxAllBytes){Kern::Printf("ETxAllBytes");} + if(aTrigger & ETxOverrun){Kern::Printf("ETxOverrun");} + if(aTrigger & ETxUnderrun){Kern::Printf("ETxUnderrun");} + + if(aTrigger & ERxAllBytes){Kern::Printf("ERxAllBytes");} + if(aTrigger & ERxOverrun){Kern::Printf("ERxOverrun");} + if(aTrigger & ERxUnderrun){Kern::Printf("ERxUnderrun");} + + if(aTrigger & EGeneralBusError){Kern::Printf("EGeneralBusError");} + if(aTrigger & EAsyncCaptChan){Kern::Printf("EAsyncCaptChan");} + + Kern::Printf("\n"); + } +#endif + + +void DChannelIicClient::SlaveCallbackFunc(TInt aChannelId, TInt aReturn, + TInt aTrigger, TInt16 aRxWords, TInt16 aTxWords, TAny* aParam) + { + __KTRACE(Kern::Printf("SlaveClientCallbackFunc(),aChannelId=0x%x,aReturn=%d,aTrigger=0x%x,aRxWords=0x%x,aTxWords=0x%x,aParam=0x%x\n",aChannelId,aReturn,aTrigger,aRxWords,aTxWords,aParam)); + + DChannelIicClient* aClient = (DChannelIicClient*) aParam; + if(aClient) + { + if(aTrigger & (EAsyncCaptChan)) + { + if(aReturn == KErrCompletion) + { + aClient->iChannelId = aChannelId; + __KTRACE(Kern::Printf("channelId %d", aChannelId)); + TInt r = aClient->RegisterSlaveBuffers(); + //AsyncCaptChan expects a KErrCompletion returned. + //If RegisterSlaveBuffers fails, the error code will be assigned to aReturn, + //then passed back to client. + if(r != KErrNone) + aReturn = r; + } + + Kern::RequestComplete(aClient->iClient, aClient->iSlaveReqStatus, aReturn); + return; + } + + if(aTrigger & (EGeneralBusError)) + { +#ifdef _DEBUG + Kern::Printf("\n\naRxWords %d", aRxWords); + Kern::Printf("aTxWords %d", aTxWords); + PrintTrigger(aReturn); +#endif + Kern::RequestComplete(aClient->iClient, aClient->iSlaveReqStatus, KErrGeneral); + return; + } + + TInt r = KErrNone; + // if there was an underrun/overrun + if(aTrigger & ETxUnderrun) + { + TPtr8 txBuf(0, 0); + + txBuf.Set((TUint8*) aClient->iTxBuf.Ptr(), aClient->iTxBuf.MaxLength(), aClient->iTxBuf.MaxLength()); + + // use aTxWords as an offset.. + if(aTxWords + 32 <= KMaxSlaveTestBufferSize) + { + r = aClient->RegisterTxBuffer(aClient->iChannelId, txBuf, 8, 32, aTxWords); + if (r != KErrNone) + { + Kern::Printf("Error Register Tx Buffer, r %d", r); + } + else + { + r = aClient->SetNotificationTrigger(aClient->iChannelId, ETxAllBytes); + if (r != KErrNone) + { + Kern::Printf("Error setting notification trigger, r %d", r); + } + } + + // updated the buffer - so return.. + return; + } + } + + // if we've finished.. + if(aReturn & (ETxAllBytes | ERxAllBytes)) + { + //PrintTrigger(aReturn); + Kern::RequestComplete(aClient->iClient, aClient->iSlaveReqStatus, KErrNone); + } + +#if 0 + TInt8* ptr = (TInt8*)aClient->iRxBuf.Ptr(); + for(TInt i = 0; i < aRxWords; ++i) + { + Kern::Printf("Rx item %d: %x", i, (TInt8)*(ptr+i)); + } +#endif + + if(aTrigger & (/*ERxAllBytes |*/ ETxAllBytes)) + { + Kern::RequestComplete(aClient->iClient, aClient->iSlaveReqStatus, KErrNone); + } + } + else + { + Kern::RequestComplete(aClient->iClient, aClient->iSlaveReqStatus, KErrGeneral); + } + + } + +TInt DChannelIicClient::SetSlaveNotificationTrigger(TUint32 aTrigger) + { + TInt r = KErrNone; + __KTRACE(Kern::Printf("DChannelIicClient::SetSlaveNotificationTrigger() aTrigger=0x%x", aTrigger)); + + if (!iChannelId) + { + __KTRACE(Kern::Printf("Channel not captured..Call CaptureSlaveChannel() first..")); + return KErrArgument; + } + + // ERxAllBytes = 0x01, + // ERxUnderrun = 0x02, + // ERxOverrun = 0x04, + // ETxAllBytes = 0x08, + // ETxUnderrun = 0x10, + // ETxOverrun = 0x20, + // EGeneralBusError = 0x40 + + r = SetNotificationTrigger(iChannelId, aTrigger); + + if (r != KErrNone) + { + __KTRACE(Kern::Printf("Error setting notification trigger, r %d", r)); + } + + return r; + } +#endif /*SLAVE_MODE*/ + +// to handle synchronous requests from the client +TInt DChannelIicClient::DoControl(TInt aId, TAny* a1, TAny* a2) + { + TInt r = KErrNone; + switch (aId) + { + case RBusCsiTestClient::ETestAudioCodecBeep: + { +#ifdef MASTER_MODE + r = TestAudioCodecBeep(0, 7, 3, 5); +#else/* MASTER_MODE */ + r = KErrNotSupported; +#endif/* MASTER_MODE */ + break; + } + case RBusCsiTestClient::ETestTransferTimeout: + { +#ifdef MASTER_MODE + r = TestTransferTimeout(); +#else/* MASTER_MODE */ + r = KErrNotSupported; +#endif/* MASTER_MODE */ + break; + } + case RBusCsiTestClient::ETestTestHalfDuplex: + { +#ifdef MASTER_MODE + r = TestHalfDuplexTransaction(); +#else /* MASTER_MODE */ + r = KErrNotSupported; +#endif /* MASTER_MODE */ + break; + } + case RBusCsiTestClient::ETestBulkTransfer: + { +#ifdef MASTER_MODE + r = TestBulkTransfer(); +#else/* MASTER_MODE */ + r = KErrNotSupported; +#endif/* MASTER_MODE */ + break; + } + case RBusCsiTestClient::ETestDuplexTransaction: + { +#ifdef MASTER_MODE + r = TestDuplexTransaction(); +#else/* MASTER_MODE */ + r = KErrNotSupported; +#endif/* MASTER_MODE */ + break; + } + case RBusCsiTestClient::ETestConfigParams: + { + // This is an asynchronous transaction - so we're using iSpiHeader member + // to copy the data from the user. +#ifdef MASTER_MODE + r = Kern::ThreadDesRead(iClient, (TDes8*) a1, *iSpiHeader, 0, KChunkShiftBy0); + if(r == KErrNone) + { + // a2 is a BusConfig value + r = TestConfigParams((TInt)a2); + } +#else/* MASTER_MODE */ + r = KErrNotSupported; +#endif/* MASTER_MODE */ + break; + } + case RBusCsiTestClient::ECaptureSlaveChannel: + { +#ifdef SLAVE_MODE + r = CaptureSlaveChannel((TInt)a1); +#else/* SLAVE_MODE */ + r = KErrNotSupported; +#endif/* SLAVE_MODE */ + break; + } + case RBusCsiTestClient::EReleaseSlaveChannel: + { +#ifdef SLAVE_MODE + r = ReleaseSlaveChannel(); +#else/* SLAVE_MODE */ + r = KErrNotSupported; +#endif/* SLAVE_MODE */ + break; + } + case RBusCsiTestClient::EQueueOneDuplexTransaction: + { +#ifdef MASTER_MODE + r = QueueOneDuplexTransaction((TInt)a1); +#else/* MASTER_MODE */ + r = KErrNotSupported; +#endif/* MASTER_MODE */ + break; + } + default: + { + __KTRACE(Kern::Printf("DChannelIicClient::DoControl():Unrecognized value for aId=0x%x\n", aId)); + r = KErrArgument; + break; + } + } + return r; + } + +// to handle asynchronous requests from the client +TInt DChannelIicClient::DoRequest(TInt aId, TRequestStatus* aStatus, TAny* a1, TAny* a2) + { + __KTRACE(Kern::Printf("DChannelIicClient::DoRequest(aId=0x%x, aStatus=0x%x, a1=0x%x, a2=0x%x\n", + aId, aStatus, a1, a2)); + + TInt r = KErrNone; + switch (aId) + { + case RBusCsiTestClient::ETestAsynTransaction: + { +#ifdef MASTER_MODE + // Create a header, and copy it's content from the User. + // it will be deleted after the transaction is completed. + TConfigSpiBufV01* spiHeader = new TConfigSpiBufV01; + if(spiHeader) + { + r = Kern::ThreadDesRead(iClient, (TDes8*) a1, *spiHeader, 0, KChunkShiftBy0); + if(r == KErrNone) + { + // a2 is a BusConfig value + r = TestAsynTransaction(aStatus, spiHeader, (TInt) a2); + } + else + { + delete spiHeader; + } + } + else + { + r = KErrNoMemory; + } +#else + r = KErrNotSupported; +#endif/*MASTER_MODE*/ + break; + } + + case (RBusCsiTestClient::ECaptureSlaveChannelAsync): + { +#ifdef SLAVE_MODE + // a1 - size + iSlaveReqStatus = aStatus; + r = CaptureSlaveChannel((TInt) a1, ETrue); +#else + r = KErrNotSupported; +#endif/*SLAVE_MODE*/ + break; + } + + case (RBusCsiTestClient::ESetSlaveNotificationTrigger): + { +#ifdef SLAVE_MODE + // a1 = trigger + iSlaveReqStatus = aStatus; + r = SetSlaveNotificationTrigger((TUint32) a1); +#else + r = KErrNotSupported; +#endif + break; + } + + default: + { + __KTRACE(Kern::Printf("DChannelIicClient::DoRequest(): unrecognized value for aId=0x%x\n", aId)); + r = KErrArgument; + break; + } + } + return r; + } + +// LDD entry point +DECLARE_STANDARD_LDD() + { + return new DDeviceIicClient; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/csi/d_csi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/csi/d_csi.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,483 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#ifndef __D_CSI_H__ +#define __D_CSI_H__ + +#ifdef __KERNEL_MODE__ +#include +#include +#endif /* __KERNEL_MODE__ */ + +const TInt KIicClientThreadPriority = 24; +const TInt KIicClientMajorVersionNumber = 1; +const TInt KIicClientMinorVersionNumber = 0; +const TInt KIicClientBuildVersionNumber = KE32BuildVersionNumber; +const TUint8 KSpiChannel0 = 0; +const TUint8 KSpiChannel1 = 1; +const TUint8 KCodecChannelNumber = KSpiChannel0; +const TInt KMaxSlaveTestBufferSize = 256; + +#ifndef __KERNEL_MODE__ + +/** + ********************************************************************************************************** + * The Following typdef are copied from iic.h. This will be replaced with a cutshort version of iic.h, + * which will have only the required information which has to be shared across user test application + * and the driver. + ********************************************************************************************************** + + */ +enum TEndianness + { + ELittleEndian, + EBigEndian + }; + + +enum TSpiWordWidth + { + ESpiWordWidth_8, + ESpiWordWidth_10, + ESpiWordWidth_12, + ESpiWordWidth_16 + }; + +/** + @publishedPartner + @prototype 9.6 + + The set of clock mode values for use with TConfigSpiV01 + + @see TConfigSpiV01 + + */ +enum TSpiClkMode + { + ESpiPolarityLowRisingEdge, // Active high, odd edges + ESpiPolarityLowFallingEdge, // Active high, even edges + ESpiPolarityHighFallingEdge, // Active low, odd edges + ESpiPolarityHighRisingEdge + // Active low, even edges + }; + +enum TSpiSsPinMode + { + ESpiCSPinActiveLow, // Active low + ESpiCSPinActiveHigh // Active high + }; + +enum TBusType + { + EI2c = 0, + ESpi = 0x01, + EMicrowire = 0x02, + ECci = 0x03, + ESccb = 0x04 + }; + +/** + @publishedPartner + @prototype 9.6 + + Class to represent the configuration data for a SPI bus channel registered with IIC + + */ + +enum TBitOrder + { + ELsbFirst, + EMsbFirst + }; + + +class TConfigSpiV01 + { +public: + TSpiWordWidth iWordWidth; + TInt32 iClkSpeedHz; + TSpiClkMode iClkMode; + TInt32 iTimeoutPeriod; + TEndianness iEndianness; + TBitOrder iBitOrder; + TUint iTransactionWaitCycles; + TSpiSsPinMode iSSPinActiveMode; + }; + +typedef TPckgBuf TConfigSpiBufV01; + + +// Bus realisation configuration +// +// 31 30 29 28 | 27 26 25 24 | 23 22 21 20 | 19 18 17 16 | 15 14 13 12 | 11 10 9 8 | 7 6 5 4 | 3 2 1 0 +// +// 31:29 - HS Master address (I2C only) +// 28 - HS address valid bit +// 27:23 - Reserved +// 22:20 - Bus type +// 19:15 - Channel number +// 14:10 - Transaction speed +// 9:0 - Slave address +#define HS_MASTER_ADDR_SHIFT 29 +#define HS_MASTER_ADDR_MASK 0x7 +#define HS_ADDR_VALID_SHIFT 28 +#define HS_ADDR_VALID_MASK 0x1 +#define BUS_TYPE_SHIFT 20 +#define BUS_TYPE_MASK 0x7 +#define CHANNEL_NO_SHIFT 15 +#define CHANNEL_NO_MASK 0x1F +#define TRANS_SPEED_SHIFT 10 +#define TRANS_SPEED_MASK 0x1F +#define SLAVE_ADDR_SHIFT 0 +#define SLAVE_ADDR_MASK 0x3FF +// +// Macros to access fields within Bus Realisation Configuration data, used on a per-transaction basis with IIC +#define SET_CONFIG_FIELD(aBusId,aField,aMask,aShift) ((aBusId)=((aBusId) &~ ((aMask)<<(aShift))) | (((aField)&(aMask)) << (aShift))) +#define GET_CONFIG_FIELD(aBusId,aMask,aShift) (((aBusId)>>(aShift))&(aMask)) + + +#define GET_HS_MASTER_ADDR(aBusId) GET_CONFIG_FIELD(aBusId,HS_MASTER_ADDR_MASK,HS_MASTER_ADDR_SHIFT) +#define SET_HS_MASTER_ADDR(aBusId,aHsMasterAddr) SET_CONFIG_FIELD(aBusId,aHsMasterAddr,HS_MASTER_ADDR_MASK,HS_MASTER_ADDR_SHIFT) +#define GET_HS_VALID(aBusId) GET_CONFIG_FIELD(aBusId,HS_ADDR_VALID_MASK,HS_ADDR_VALID_SHIFT) +#define SET_HS_VALID(aBusId,aHsValid) SET_CONFIG_FIELD(aBusId,aHsValid,HS_ADDR_VALID_MASK,HS_ADDR_VALID_SHIFT) +#define GET_BUS_TYPE(aBusId) GET_CONFIG_FIELD(aBusId,BUS_TYPE_MASK,BUS_TYPE_SHIFT) +#define SET_BUS_TYPE(aBusId,aBusType) SET_CONFIG_FIELD(aBusId,aBusType,BUS_TYPE_MASK,BUS_TYPE_SHIFT) +#define GET_CHAN_NUM(aBusId) GET_CONFIG_FIELD(aBusId,CHANNEL_NO_MASK,CHANNEL_NO_SHIFT) +#define SET_CHAN_NUM(aBusId,aChanNum) SET_CONFIG_FIELD(aBusId,aChanNum,CHANNEL_NO_MASK,CHANNEL_NO_SHIFT) +#define SET_TRANS_SPEED(aBusId,aTransSpeed) SET_CONFIG_FIELD(aBusId,aTransSpeed,TRANS_SPEED_MASK,TRANS_SPEED_SHIFT) +#define GET_TRANS_SPEED(aBusId) GET_CONFIG_FIELD(aBusId,TRANS_SPEED_MASK,TRANS_SPEED_SHIFT) +#define SET_SLAVE_ADDR(aBusId,aSlaveAddr) SET_CONFIG_FIELD(aBusId,aSlaveAddr,SLAVE_ADDR_MASK,SLAVE_ADDR_SHIFT) +#define GET_SLAVE_ADDR(aBusId) GET_CONFIG_FIELD(aBusId,SLAVE_ADDR_MASK,SLAVE_ADDR_SHIFT) + + +// Forward declarations +class TIicBusTransaction; +class DIicBusChannelMaster; + +/** + @publishedPartner + @prototype 9.6 + + Class to represent and provide access to configuration data used on a per-transaction basis with IIC + + @see TIicBusTransaction + + */ +class TIicBusTransfer + { +public: + enum TReqType + { + EMasterRead, + EMasterWrite + }; + // the client interface for creating and linking simple requests + inline TIicBusTransfer(TReqType aType, TInt8 aGranularity, TDes8* aBuffer) : + iType((TInt8) aType), iNext(NULL) + { + iBufGranularity = aGranularity; + iBuffer = aBuffer; + } + inline void LinkAfter(TIicBusTransfer* aPrev) + { + iNext = aPrev; + } + inline TInt8 WordWidth() + { + return iBufGranularity; + } + inline TReqType Direction() + { + return (TReqType) iType; + } + inline TInt Length() + { + TInt8 granularityInBytes = (TInt8)(((iBufGranularity - 1) >> 3) + 1); + return (iBuffer->Size() / granularityInBytes); + } + inline const TIicBusTransfer* Next() + { + return iNext; + } +private: + TInt8 iType; // as one of TReqType + TInt8 iBufGranularity; // width of a transfer word in bits + TInt8 iSpare1; + TInt8 iSpare2; + const TDes8* iBuffer; // the data for this transfer (packed into 8-bit words with padding) + TIicBusTransfer* iNext; + + friend class DIicBusChannelMaster; + }; + +#endif //End of Temporarily inclusion + +struct TUsideTracnDesc + { + TDes8* iHeader; + TIicBusTransfer* iHalfDuplexTrans; + TIicBusTransfer* iFullDuplexTrans; + TUint8 iFlags; // used to indicate if it supports a preamble + TAny* iPreambleArg; // used for preamble argument + TAny* iMultiTranscArg; // used for multi transc argument + }; + +class RBusCsiTestClient: public RBusLogicalChannel + { +public: + enum TControl + { + ETestAudioCodecBeep, + ETestTransferTimeout, + ETestBulkTransfer, + ETestTestHalfDuplex, + ETestDuplexTransaction, + ETestConfigParams, + ECaptureSlaveChannel, + EReleaseSlaveChannel, + EQueueOneDuplexTransaction + }; + + enum TRequest + { + ECaptureSlaveChannelAsync, + ESetSlaveNotificationTrigger, + ETestAsynTransaction + }; + +#ifndef __KERNEL_MODE__ + +public: + TInt Open(TDesC& aProxyName) + {return (DoCreate(aProxyName,TVersion(KIicClientMajorVersionNumber,KIicClientMinorVersionNumber,KIicClientBuildVersionNumber),-1,NULL,NULL,EOwnerThread));} + + // test-cases + TInt TestAudioCodecBeep() + {return DoControl(ETestAudioCodecBeep);} + + TInt TestTransferTimeout() + {return DoControl(ETestTransferTimeout);} + + TInt TestHalfDuplex() + {return DoControl(ETestTestHalfDuplex);} + + TInt TestBulkTransfer() + {return DoControl(ETestBulkTransfer);} + + TInt TestDuplexTransaction() + {return DoControl(ETestDuplexTransaction);} + + TInt TestConfigParams(TConfigSpiBufV01 *aSpiHeader, TUint32 aBusId) + {return DoControl(ETestConfigParams, (TAny*)aSpiHeader, (TAny*)aBusId);} + + void CaptureSlaveChannel(TInt aBufSize, TRequestStatus &aStatus) + {DoRequest(ECaptureSlaveChannelAsync, aStatus, (TAny*)aBufSize);} + + TInt CaptureSlaveChannel(TInt aBufSize) + {return DoControl(ECaptureSlaveChannel, (TAny*)aBufSize);} + + TInt ReleaseSlaveChannel() + {return(DoControl(EReleaseSlaveChannel));} + + void SetSlaveNotificationTrigger(TRequestStatus &aStatus, TUint32 aTrigger) + {DoRequest(ESetSlaveNotificationTrigger, aStatus, (TAny*) aTrigger);} + + TInt QueueOneDuplexTransaction(TInt aSize) + {return DoControl(EQueueOneDuplexTransaction, (TAny*)aSize);} + + void TestAsynTransaction(TRequestStatus &aStatus, TConfigSpiBufV01* aSpiHeader, TUint32 aBusId) + {DoRequest(ETestAsynTransaction, aStatus, (TAny*)aSpiHeader, (TAny*)aBusId);} + +#endif + }; + +#ifdef __KERNEL_MODE__ +struct TCapsIicClient + { + TVersion version; + }; + +class DDeviceIicClient: public DLogicalDevice + { +public: + DDeviceIicClient(); + ~DDeviceIicClient(); + virtual TInt Install(); + virtual void GetCaps(TDes8 &aDes) const; + virtual TInt Create(DLogicalChannelBase*& aChannel); + }; + +// declaration for the client channel +class DChannelIicClient: public DLogicalChannel + { +public: + DChannelIicClient(); + ~DChannelIicClient(); + virtual TInt DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); + +protected: + virtual void HandleMsg(TMessageBase* aMsg); // Note: this is a pure virtual in DLogicalChannel + + void DoCancel(TInt aMask); + TInt DoControl(TInt aId, TAny* a1, TAny* a2); + TInt DoRequest(TInt aId, TRequestStatus* aStatus, TAny* a1, TAny* a2); + +private: + +#ifdef SLAVE_MODE + TInt RegisterRxBuffer(TInt aChannelId, TPtr8 aRxBuffer, TInt8 aBufGranularity, TInt8 aNumWords, TInt8 aOffset); + TInt RegisterTxBuffer(TInt aChannelId, TPtr8 aRxBuffer, TInt8 aBufGranularity, TInt8 aNumWords, TInt8 aOffset); + TInt CaptureChannel(TInt aBusId, TDes8* aConfigHdr, TIicBusSlaveCallback* aCallback, TInt& aChannelId, TBool aAsynch); + TInt ReleaseChannel(TInt aChannelId); + TInt SetNotificationTrigger(TInt aChannelId, TInt aTrigger); +#endif + +#ifdef MASTER_MODE + TInt QueueTransaction(TInt aBusId, TIicBusTransaction* aTransaction, TIicBusCallback *aCallback=NULL); + inline TInt QueueRegisterWriteTransaction(TInt16 aRegister, TInt16 aValue, TIicBusTransaction* aTrans, TInt aConfig); + TInt TestAudioCodecBeep(TUint8 aFreq, TUint8 aTime, TUint8 aOffTime, + TUint8 aVolume, TBool aRepeat = 0); + TInt TestBulkTransfer(); + TInt TestHalfDuplexTransaction(); + TInt TestTransferTimeout(); + TInt TestDuplexTransaction(); + TInt TestConfigParams(TInt aBusId); + + static void AsyncTransCallbackFunc(TIicBusTransaction* aTrans, TInt aBusId, TInt aResult, TAny* aParam); + TInt TestAsynTransaction(TRequestStatus* aStatus,TConfigSpiBufV01* aSpiHeader, TInt aBusId); +#endif + + TDynamicDfcQue* iDfcQue; // Kernel thread for the test driver + + // Header which is common to all transactions + TConfigSpiBufV01* iSpiHeader; + // member shared in all transfers + TUint32 iCsiBusId; + +#ifdef MASTER_MODE + // codec test related member - to not pass it on every call to QueueRegisterWriteTransaction() + TPckgBuf iTransBuff; +#endif + +#ifdef SLAVE_MODE + // Slave test.. + // Slave callback function: + static void SlaveCallbackFunc(TInt aChannelId, TInt aReturn, TInt aTrigger, TInt16 aRxWords, TInt16 aTxWords, TAny* aParam); + + TInt RegisterSlaveBuffers(); + TInt CaptureSlaveChannel(TInt aBufSize, TBool aAsync = EFalse); + TInt ReleaseSlaveChannel(); + TInt SetSlaveNotificationTrigger(TUint32 aTrigger); + + // The object is created on the heap and buffers are needed for the whole + // time the object exists on the heap, so these buffers can be a part of the object(as they are used in all tests) + // buffers for the Slave.. + TBuf8 iTxBuf; // buffer.. + TBuf8 iRxBuf; // buffer.. + TInt iSlaveBufSize; + + TInt iChannelId; // cookie for SlaveChannel - assigned when capturing the channel.. + TRequestStatus* iSlaveReqStatus; +#endif + + // Master callback function (used when queuing an asynch master transaction) + static void MasterCallbackFunc(TIicBusTransaction* aTransction, TInt aBusId, TInt aResult, TAny* aParam); + TInt QueueOneDuplexTransaction(TInt aSize); + // transaction for the Master's asynchronous transaction.. + TIicBusTransaction iMasterTransaction; + TIicBusSlaveCallback *iSlaveCallback; + TIicBusCallback *iMasterCallback; +#ifdef STANDALONE_CHANNEL +#ifdef MASTER_MODE + DCsiChannelMaster* iMasterChannel; +#endif/*Master mode*/ + +#ifdef SLAVE_MODE + DCsiChannelSlave* iSlaveChannel; +#endif/*Slave mode*/ +#endif /*STANDALONE_CHANNEL*/ + DThread* iClient; + }; + + +//Class to be passed along with Asynchronous Transaction. +#ifdef MASTER_MODE +template +class TCallBckRequest + { +public: + TCallBckRequest(DThread* aClient, TRequestStatus* aReqStatus, TConfigSpiBufV01* aHeader) : + iClient(aClient), + iReqStatus(aReqStatus), + iHeader(aHeader), + iCallback(NULL) + {} + + TCallBckRequest() : iClient(NULL), iReqStatus(NULL), iHeader(NULL), iCallback(NULL) + { + for(TUint i = 0; i= 0 && index < dim, ) + return iTransfers[index]; + } + + inline TIicBusTransfer* GetBuffer(TInt index) + { + // __ASSERT_DEBUG(index >= 0 && index < dim, ) + return iBuffers[index]; + } + + // destructor. + inline ~TCallBckRequest() + { + delete iHeader; + delete iCallback; + for(TUint i = 0; i +#include +#include +#include +#include +#include "d_csi.h" + +_LIT(testName,"t_csi"); +_LIT(KLddFileName, "d_csi.ldd"); // Kernel-side proxy LDD acting as a client of the IIC +_LIT(KLddFileNameRoot, "d_csi"); + +// global data.. +GLDEF_D RTest csiTest(testName); +GLDEF_D RBusCsiTestClient gCsiLdd; // Channel to kernel-side proxy +GLDEF_D TConfigSpiBufV01 SpiHeader; +GLDEF_D TUint32 SpiConfig; + +LOCAL_C void SetDefaultHeader() + { + const TConfigSpiV01 DefaultHeader = + { + ESpiWordWidth_8, //iWordWidth + 260000, //iClkSpeed + ESpiPolarityLowRisingEdge, //iClkMode + 500, // iTimeoutPeriod + EBigEndian, // iEndianness + EMsbFirst, //iBitOrder + 0, //iTransactionWaitCycles + ESpiCSPinActiveLow //iCsPinActiveMode + }; + + SpiHeader = DefaultHeader; + } + +LOCAL_C void SetDefaultConfig() + { + //Set the default settings + SpiConfig = 0; + SET_CHAN_NUM(SpiConfig,KSpiChannel0); //0 or + SET_BUS_TYPE(SpiConfig,ESpi); + SET_SLAVE_ADDR(SpiConfig,1); // Any Number between 1 to 32 */ + SetDefaultHeader(); + } + +// ================== +// MASTER tests +// clock values supported by the navi-engine CSI interface +const TUint32 TSpiClkSpeedValues[] = + {130000, 260000, 521000, 1040000, 2080000, 4170000, 16670000}; + +LOCAL_C void TestClockSpeed() + { + TInt r = KErrNone; + + // try to set each of the supported clk speeds. (queuing a transaction using + // header with one of them set).. + for(TUint i = 0; i < sizeof(TSpiClkSpeedValues) / sizeof(TUint32); ++i) + { + SpiHeader().iClkSpeedHz = TSpiClkSpeedValues[i]; + r = gCsiLdd.TestConfigParams(&SpiHeader, SpiConfig); + csiTest(r == KErrNone); + } + + // now try some of known - as not supported: + SpiHeader().iClkSpeedHz = 300000; + r = gCsiLdd.TestConfigParams(&SpiHeader, SpiConfig); + if(r != KErrNotSupported) + { + csiTest.Printf(_L("Error setting clk %d, r = %d \n"), SpiHeader().iClkSpeedHz, r); + csiTest(EFalse); + } + // Set it to the default header after testing + SetDefaultHeader(); + } + + +LOCAL_C void TestWordWidth() + { + TInt r = KErrNone; + for (TInt i = 0; i <= ESpiWordWidth_16; i++) + { + SpiHeader().iWordWidth = static_cast (i); + r = gCsiLdd.TestConfigParams(&SpiHeader, SpiConfig); + switch (i) + { + case ESpiWordWidth_8: + case ESpiWordWidth_16: + + csiTest(r == KErrNone); + break; + default: + csiTest(r == KErrNotSupported); + break; + }//Switch + } //For loop + //Set it to the default header after testing + SetDefaultHeader(); + } + +LOCAL_C void TestAsynchTransactions() + { + // Queue 3 asynchronous Transaction and expect them to nogified in FIFO order. + const TInt KNumberOfTransactions = 3; + TRequestStatus status[KNumberOfTransactions]; + + TInt r = KErrNone; + + for(TInt i = 0; i < KNumberOfTransactions; ++i) + { + status[i] = KErrNotReady; + gCsiLdd.TestAsynTransaction(status[i], &SpiHeader, SpiConfig); + } + + // And Expect them to be notified in the same order. + for(TInt i = 0; i < KNumberOfTransactions; ++i) + { + User::WaitForAnyRequest(); + + // next should be finished.. + if(status[i] != KErrNone) + { + r = KErrGeneral; + continue; + } + + if(i == 0) // only first should be ready.. + { + if((status[1] == KErrNone) || + (status[2] == KErrNone)) + { + r = KErrGeneral; + continue; + } + } + + if(i == 1) // only first two should be ready.. + { + if(status[2] == KErrNone) + { + r = KErrGeneral; + } + } + } + + csiTest(r == KErrNone); + } + +LOCAL_C void TestMaster() + { + TInt r = KErrNone; + + // Instigate AudioCodecBeep + csiTest.Printf(_L("Testing Audio Codec Beep\n")); + r = gCsiLdd.TestAudioCodecBeep(); + if(r == KErrNotSupported) + { + csiTest.Printf(_L("Master mode is not supported by the client, skipping master test.. \n")); + return; + } + csiTest(r == KErrNone); + + // Instigate TransferTimeout + csiTest.Printf(_L("Testing Transfer Timeout\n")); + r = gCsiLdd.TestTransferTimeout(); + csiTest(r == KErrNone); + + // Test TestBulkTransfer + csiTest.Printf(_L("Testing TestBulkTransfer\n")); + r = gCsiLdd.TestBulkTransfer(); + csiTest(r == KErrNone); + + // Test Half Duplex + csiTest.Printf(_L("Testing Half Duplex operations \n")); + r = gCsiLdd.TestHalfDuplex(); + csiTest(r == KErrNone); + + // TestDuplexTransaction + csiTest.Printf(_L("Testing DuplexTransaction\n")); + r = gCsiLdd.TestDuplexTransaction(); + csiTest(r == KErrNone); + + // Test all available ClockSpeeds + csiTest.Printf(_L("Testing Different ClockSpeeds\n")); + TestClockSpeed(); + + // Test WordWidth + csiTest.Printf(_L("Testing WordWidths\n")); + TestWordWidth(); + + csiTest.Printf(_L("Testing Asynchronous Transactions\n")); + TestAsynchTransactions(); + } + +// ================== +// SLAVE tests +LOCAL_C TInt SlaveCaptureChannel(TInt aBufferSize) + { + csiTest.Printf(_L("SlaveCaptureChannel(), buff %d\n"), aBufferSize); + // Open Slave channel (use buffers declared in the d_csi) + TInt r = gCsiLdd.CaptureSlaveChannel(aBufferSize); + if(r != KErrNone) + { + csiTest.Printf(_L("couln't Capture Slave Channel, r= %d\n"), r); + } + return r; + } + +LOCAL_C TInt SlaveAsyncCaptureChannel(TInt aBufferSize) + { + // Open Slave channel (use buffers declared in the d_csi) + TRequestStatus status; + TInt r = KErrNone; + + gCsiLdd.CaptureSlaveChannel(aBufferSize, status); + + User::WaitForRequest(status); + r = status.Int(); + if (r != KErrCompletion) + { + csiTest.Printf(_L("SlaveAsyncCaptureChannel request returned, r= %d\n"), r); + } + return r; + } + +LOCAL_C TInt SlaveReleaseChannel() + { + TInt r = gCsiLdd.ReleaseSlaveChannel(); + if (r != KErrNone) + { + csiTest.Printf(_L("couln't Release Slave Channel, r= %d\n"), r); + } + return r; + } + +#ifdef EXTERNAL_HW_LOOPBACK_USED +LOCAL_C void StartSlaveRequest(TRequestStatus &aStatus) + { + csiTest.Printf(_L("StartSlaveRequest\n")); + + enum TTriggers + { + ERxAllBytes = 0x01, + ERxUnderrun = 0x02, + ERxOverrun = 0x04, + ETxAllBytes = 0x08, + ETxUnderrun = 0x10, + ETxOverrun = 0x20, + EGeneralBusError = 0x40 + }; + + // register for all possible notifications.. + TInt trigger = ERxAllBytes | ERxOverrun | ERxUnderrun | ETxAllBytes | ETxOverrun | ETxUnderrun; + + // Set notification trigger - this starts asynchronous Slave operation.. + csiTest.Printf(_L("Set Notification trigger\n")); + gCsiLdd.SetSlaveNotificationTrigger(aStatus, trigger); + } + +LOCAL_C TInt WaitForSlaveReqest(TRequestStatus &aStatus) + { + csiTest.Printf(_L("Waiting for the slave to complete..\n")); + User::WaitForRequest(aStatus); + TInt r = aStatus.Int(); + if(r != KErrNone) + { + csiTest.Printf(_L("request returned, r= %d\n"), r); + } + return r; + } + +// Requirements: local-HW loopback between CSI channel 0 (master) and 1 (Slave) +// in this test scenario we will: +// 1. Initiate Asynchronous, full duplex Slave operation with buffers set 64 Bytes +// 2. Queue one full duplex Master transfer with 64 bytes +// 3. Wait and check the SlaveRequest competition +LOCAL_C TInt TestSlaveNormalTransfer() + { + csiTest.Printf(_L("TestSlaveNormalTransfer()\n")); + // capture the channel + TInt r = SlaveCaptureChannel(64); + csiTest(r == KErrNone); + + // instigate the request.. + TRequestStatus status; + StartSlaveRequest(status); + + // queue One FullDuplex transaction.. + // (it can be either synchronous or asynchronous) + // specify both MASTER_MODE and SLAVE_MODE to run the test + csiTest.Printf(_L("QueueOneDuplexTransaction\n")); + r = gCsiLdd.QueueOneDuplexTransaction(64); + + if (r == KErrNone) + { + csiTest.Printf(_L("WaitForSlaveRequest\n")); + r = WaitForSlaveReqest(status); + } + else if (r == KErrNotSupported) + { + return r; + } + else + { + csiTest.Printf(_L("Error queuing duplex trans?\n")); + } + + // release the channel.. + SlaveReleaseChannel(); + + return r; + } +#endif + +LOCAL_C void TestSlave() + { + csiTest.Printf(_L("TestSlave operations\n")); + TInt r = KErrNone; + + csiTest.Printf(_L("Capture channel\n")); + r = SlaveCaptureChannel(64); + if(r == KErrNotSupported) + { + csiTest.Printf(_L("Slave mode is not supported by the client, skipping slave tests.. \n")); + return; + } + csiTest(r == KErrNone); + + csiTest.Printf(_L("Capture already captured channel\n")); + r = SlaveCaptureChannel(64); + csiTest(r == KErrInUse); + + csiTest.Printf(_L("Release channel\n")); + r = SlaveReleaseChannel(); + + csiTest.Printf(_L("Asynchronously capture channel\n")); + r = SlaveAsyncCaptureChannel(64); + csiTest(r == KErrCompletion); + + csiTest.Printf(_L("Release channel\n")); + r = SlaveReleaseChannel(); + +#ifdef EXTERNAL_HW_LOOPBACK_USED + // this test needs additional HW loopback (channel 0 and 1) attached to the board + r = TestSlaveNormalTransfer(); + if(r == KErrNotSupported) + { + csiTest.Printf(_L("TestSlaveNormalTransfer() is not supported for slave only mode \n")); + return; + } + csiTest(r == KErrNone); +#endif + } + + +LOCAL_C void LoadTestDriver() + { + // csiTest.Printf(_L("Loading the proxy-device driver\n")); + TInt r = User::LoadLogicalDevice(KLddFileName); + if(r != KErrNone && r != KErrAlreadyExists) + { + csiTest.Printf(_L("Failed to load the proxy-device driver, r= %d\n"), r); + csiTest.End(); + } + } + +LOCAL_C void OpenTestDriver() + { + // Open a Master SPI channel to the kernel side proxy + TBufC<6> proxyName(KLddFileNameRoot); + // csiTest.Printf(_L("opening the proxy-device driver\n")); + TInt r = gCsiLdd.Open(proxyName); + if(r != KErrNone) + { + csiTest.Printf(_L("Failed to open the proxy-device the driver, r= %d\n"), r); + csiTest(r == KErrNone); + } + //Have the default config + SetDefaultConfig(); + } + +LOCAL_C void UnloadTestDriver() + { + TInt r = User::FreeLogicalDevice(KLddFileName); + if(r != KErrNone) + { + csiTest.Printf(_L("Failed to unload the proxy-device driver, r= %d\n"), r); + } + } + +/************************************************* + *********Main************************************ + ************************************************/ +EXPORT_C TInt E32Main() + { + csiTest.Title(); + csiTest.Start(_L("Test CSI Master \n")); + + //Load the Test Driver + LoadTestDriver(); + __KHEAP_MARK; + + OpenTestDriver(); + + // Run tests for the Slave + TestMaster(); + + // Run tests for the Slave + TestSlave(); + + //Close the driver + csiTest.Printf(_L("Tests completed OK, about to close channel\n")); + + gCsiLdd.Close(); + + __KHEAP_MARKEND; + + UnloadTestDriver(); + csiTest.End(); + + return KErrNone; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/d_csi.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/d_csi.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file + +@SYMPurpose proxy device-driver for naviEngine CSI testing +*/ + +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "kernel/kern_ext.mmh" +#include "../csi_config.mmh" + +target VariantTarget(d_csi,ldd) +romtarget d_csi.ldd + +targettype ldd +sourcepath ./csi +source d_csi.cpp + +USERINCLUDE ../../naviengine_assp +USERINCLUDE ../inc +USERINCLUDE ../../../../../os/kernelhwsrv/kernel/eka/drivers/iic +OS_LAYER_SYSTEMINCLUDE_SYMBIAN +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + +#ifdef __USE_MASTER_MODE__ +macro MASTER_MODE +#endif + +#ifdef __USE_SLAVE_MODE__ +macro SLAVE_MODE +#endif + +library iic.lib +library VariantTarget(gpio,lib) + +uid 0x100000af +vendorid 0x70000001 + +capability all +epocallowdlldata + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/d_csi_ctrless.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/d_csi_ctrless.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file + +@SYMPurpose proxy device-driver for naviEngine CSI testing +*/ + +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ +macro STANDALONE_CHANNEL + +#include +#include "kernel/kern_ext.mmh" +#include "../csi_config.mmh" + +target VariantTarget(d_csi_ctrless,ldd) +romtarget d_csi_ctrless.ldd + +targettype ldd +sourcepath ./csi +source d_csi.cpp + + +userinclude ../../naviengine_assp/csi +userinclude ../inc + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +#ifdef __USE_MASTER_MODE__ +macro MASTER_MODE +#endif + +#ifdef __USE_SLAVE_MODE__ +macro SLAVE_MODE +#endif + +library VariantTarget(csi_ctrless,lib) +library VariantTarget(gpio,lib) + +uid 0x100000af +vendorid 0x70000001 + +capability all +epocallowdlldata + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/d_frqchg.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/d_frqchg.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,21 @@ +// Copyright (c) 2010-2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// d_frqchg.mmp +// +// + + +#include + +#include "../../../../../os/kernelhwsrv/kerneltest/e32test/group/d_frqchg.mmh" diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/d_gpio.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/d_gpio.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(d_gpio,ldd) +romtarget d_gpio.ldd +targettype ldd + +SYMBIAN_BASE_SYSTEMINCLUDE(assp/naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) +SYMBIAN_BASE_SYSTEMINCLUDE(e32test) +userinclude ../../naviengine_assp/ + +sourcepath gpio/ +source d_gpio.cpp + +/* sourcepath ../../naviengine_assp/ +source gpio.cpp +*/ +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +library VariantTarget(kanaviengine,lib) +library VariantTarget(gpio,lib) + +capability all + +vendorid 0x70000001 +epocallowdlldata + +SMPSAFE \ No newline at end of file diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/d_pci.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/d_pci.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include <../variant.mmh> +#include "kernel/kern_ext.mmh" + +target VariantTarget(d_pci,ldd) +romtarget d_pci.ldd +targettype ldd + +SYMBIAN_BASE_SYSTEMINCLUDE(assp/naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) +SYMBIAN_BASE_SYSTEMINCLUDE(e32test) +userinclude ../../naviengine_assp/pci + +sourcepath ./pci +source d_pci.cpp + +sourcepath ../../naviengine_assp/pci +source allocator.cpp + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +library VariantTarget(kanaviengine,lib) +library VariantTarget(pci,lib) + +capability all + +vendorid 0x70000001 +epocallowdlldata + +SMPSAFE \ No newline at end of file diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/d_timestamppdd.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/d_timestamppdd.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file + +@SYMPurpose +*/ + + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(d_timestamp,pdd) +romtarget d_timestamp.pdd + +targettype pdd +sourcepath ./timestamp +source d_timestamp.cpp + +SYMBIAN_BASE_SYSTEMINCLUDE(assp/naviengine) +userinclude ../inc +#if defined(SMP) +USERINCLUDE ../../../../../os/kernelhwsrv/kernel/eka/include/drivers/smppower/sample_idlehandler +#endif + +userinclude ../../../../../os/kernelhwsrv/kerneltest/e32test/timestamp/ +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +library VariantTarget(power,lib) + +vendorid 0x70000001 + +capability all +epocallowdlldata + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/gpio/d_gpio.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/gpio/d_gpio.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,155 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include +#include "d_gpio.h" +#include "d_gpio_dev.h" + +#define ETestStaticExtension 0x80000000 + +_LIT(KGpioDfscQueName, "D_GPIO_DFC"); + +DECLARE_STANDARD_LDD() + { + return new DGpioFactory; + } + +DGpioFactory::DGpioFactory() + { + // Set version number for this device + iVersion=RGpio::VersionRequired(); + iParseMask=0; + } + +TInt DGpioFactory::Install() + { + return SetName(&RGpio::Name()); + } + +DGpioFactory::~DGpioFactory() + { + } + +void DGpioFactory::GetCaps(TDes8& aDes) const + { + // Create a capabilities object + RGpio::TCaps caps; + caps.iVersion = iVersion; + // Write it back to user memory + Kern::InfoCopy(aDes,(TUint8*)&caps,sizeof(caps)); + } + +TInt DGpioFactory::Create(DLogicalChannelBase*& aChannel) + { + aChannel=new DGpioChannel; + if(!aChannel) + return KErrNoMemory; + + return KErrNone; + } + +DGpioChannel::DGpioChannel() + { + iClient=&Kern::CurrentThread(); + iClient->Open(); + } + +TInt DGpioChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer) + { + TDynamicDfcQue* dfcq = NULL; + TInt r = Kern::DynamicDfcQCreate(dfcq, 27, KGpioDfscQueName); + + if(r == KErrNone) + { + iDfcQ = dfcq; + SetDfcQ(iDfcQ); + iMsgQ.Receive(); + } + return r; + } + +DGpioChannel::~DGpioChannel() + { + ((TDynamicDfcQue*)iDfcQ)->Destroy(); + Kern::SafeClose((DObject*&)iClient,NULL); + } + +TInt DGpioChannel::RequestUserHandle(DThread* aThread, TOwnerType aType) + { + // Make sure that only our client can get a handle + if (aType!=EOwnerThread || aThread!=iClient) + return KErrAccessDenied; + return KErrNone; + } + +void DGpioChannel::HandleMsg(TMessageBase* aMsg) + { + TThreadMessage& m=*(TThreadMessage*)aMsg; + + // Get message type + TInt id=m.iValue; + + // Decode the message type and dispatch it to the relevent handler function... + + if (id==(TInt)ECloseMsg) + { + m.Complete(KErrNone, EFalse); + return; + } + + if (id==KMaxTInt) + { + m.Complete(KErrNone,ETrue); + return; + } + + if (id<0) + { + TInt r=DoControl(id); + m.Complete(r, KErrNotSupported); + } + else + { + // DoControl + TInt r=DoControl(id); + m.Complete(r,ETrue); + } + } + +/** + Process synchronous 'control' requests +*/ +TInt DGpioChannel::DoControl(TInt aFunction) + { + TInt r=KErrNone; + + switch (aFunction) + { + case RGpio::ECallStaticExtension: + r = GPIO::StaticExtension(0, ETestStaticExtension, NULL, NULL); + break; + + default: + r = KErrNotSupported; + break; + } + + return r; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/gpio/d_gpio.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/gpio/d_gpio.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef __D_GPIO_H__ +#define __D_GPIO_H__ + +#include +#include +#include + +#ifndef __KERNEL_MODE__ +#include +#endif + +class RGpio : public RBusLogicalChannel + { +public: + class TCaps + { + public: + TVersion iVersion; + }; + +public: + TInt Open(); + TInt CallStaticExtension(); + inline static const TDesC& Name(); + inline static TVersion VersionRequired(); + enum TControl + { + ECallStaticExtension = 0x8fff + }; + + // Kernel side LDD channel is a friend + //friend class DGpioChannel; + }; + +inline const TDesC& RGpio::Name() + { + _LIT(KGpioName,"GPIO"); + return KGpioName; + } + +inline TVersion RGpio::VersionRequired() + { + const TInt KMajorVersionNumber=1; + const TInt KMinorVersionNumber=0; + const TInt KBuildVersionNumber=KE32BuildVersionNumber; + return TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); + } + +#ifndef __KERNEL_MODE__ + +TInt RGpio::Open() + { + return DoCreate(Name(),VersionRequired(),KNullUnit,NULL,NULL,EOwnerThread); + } + +TInt RGpio::CallStaticExtension() + { + return DoControl(ECallStaticExtension, NULL); + } + +#endif // !__KERNEL_MODE__ + +#endif // __GPIO_H__ + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/gpio/d_gpio_dev.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/gpio/d_gpio_dev.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef __D_GPIO_DEV_H__ +#define __D_GPIO_DEV_H__ + +class DGpioFactory : public DLogicalDevice + { +public: + DGpioFactory(); + ~DGpioFactory(); + virtual TInt Install(); + virtual void GetCaps(TDes8& aDes) const; + virtual TInt Create(DLogicalChannelBase*& aChannel); + }; + +class DGpioChannel : public DLogicalChannel + { +public: + DGpioChannel(); + virtual ~DGpioChannel(); + + virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType); + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); + virtual void HandleMsg(TMessageBase* aMsg); +private: + enum TPanic + { + ERequestAlreadyPending = 1 + }; + TInt DoControl(TInt aFunction); +private: + DThread* iClient; + }; + +#endif // __GPIO_DEV_H__ + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/gpio/t_gpio.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/gpio/t_gpio.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include +#include +#include "d_gpio.h" + +_LIT(testName, "t_gpio"); +_LIT(KLddFileName, "d_gpio.ldd"); + +LOCAL_D RTest test(testName); + +GLDEF_C TInt E32Main() + { + test.Title(); + + TInt r; + + test.Start(_L("Load Logical Device")); + r = User::LoadLogicalDevice(KLddFileName); + test(r == KErrNone || r == KErrAlreadyExists); + + __KHEAP_MARK; + + test.Next(_L("Open Device")); + RDevice device; + r = device.Open(RGpio::Name()); + test(r == KErrNone); + + test.Next(_L("Open Logical Channel")); + RGpio ldd; + r = ldd.Open(); + test(r == KErrNone); + + test.Next(_L("Call Static Extension")); + r = ldd.CallStaticExtension(); + test(r == KErrNone); + + test.Next(_L("Close Logical Channel")); + ldd.Close(); + + __KHEAP_MARKEND; + + test.Next(_L("Unload Logical Device")); + r = User::FreeLogicalDevice(KLddFileName); + test(r == KErrNone); + + test.End(); + + return 0; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/mediaext/d_nfe.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/mediaext/d_nfe.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,53 @@ +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution.// +// Contributors: +// +// Description: +// e32test\group\d_nfe.mmp +// +// + +/** +@file + +@SYMPurpose medtestnfe.pdd NFE test Media Driver +*/ + +#include "../variant.mmh" + +target VariantTarget(medtestnfe,pdd) + +targettype pdd + +#include "kernel/kern_ext.mmh" +#include "drivers/elocd.mmh" + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +// point to variantmediadef.h +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) + +sourcepath ../../../../../../os/kernelhwsrv/kerneltest/e32test/mediaext +source d_nfe.cpp +library elocd.lib + +start wins +win32_headers +end + +epocallowdlldata + +uid 0x100039d0 0xA000E7C5 +VENDORID 0x70000001 +capability all + + + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/nanddemandpaginge32tests.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/nanddemandpaginge32tests.bat Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,19 @@ +@rem +@rem Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +@rem All rights reserved. +@rem This component and the accompanying materials are made available +@rem under the terms of "Eclipse Public License v1.0" +@rem which accompanies this distribution, and is available +@rem at the URL "http://www.eclipse.org/legal/epl-v10.html". +@rem +@rem Initial Contributors: +@rem Nokia Corporation - initial contribution. +@rem +@rem Contributors: +@rem +@rem Description: +@rem + +T_DEMANDPAGING +T_CODEPAGING +T_DATAPAGING diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/nandtest_fulltest_autoexec.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/nandtest_fulltest_autoexec.bat Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,55 @@ +@rem +@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +@rem All rights reserved. +@rem This component and the accompanying materials are made available +@rem under the terms of "Eclipse Public License v1.0" +@rem which accompanies this distribution, and is available +@rem at the URL "http://www.eclipse.org/legal/epl-v10.html". +@rem +@rem Initial Contributors: +@rem Nokia Corporation - initial contribution. +@rem +@rem Contributors: +@rem +@rem Description: +@rem +z: + +format c: +format d: /e +format d: +format i: +format j: +rem demand paging tests (which may do nothing on non-paging ROMs): +runtests nanddemandpaginge32tests.bat -st -t 40 -c + +trace on 65 +z: +cd test + +format c: +format d: /e +format d: +format i: +runtests e32test.auto.bat -st -t 40 -c +format c: +format d: /e +format d: +format i: +runtests loader.auto.bat -st -t 180 -c +format c: +format d: /e +format d: +format i: +runtests f32test.auto.bat -d c -st -t 60 -c +format c: +format d: /e +format d: +format i: +runtests f32test.auto.bat -d d -st -t 180 -c +format c: +format d: /e +format d: +format i: +runtests f32test.auto.bat -d i -st -t 90 -c +runtests rofs.auto.bat -d z -t 30 -p -c diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/nandtest_load_autoexec.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/nandtest_load_autoexec.bat Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,19 @@ +@rem +@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +@rem All rights reserved. +@rem This component and the accompanying materials are made available +@rem under the terms of "Eclipse Public License v1.0" +@rem which accompanies this distribution, and is available +@rem at the URL "http://www.eclipse.org/legal/epl-v10.html". +@rem +@rem Initial Contributors: +@rem Nokia Corporation - initial contribution. +@rem +@rem Contributors: +@rem +@rem Description: +@rem + +z: +nandloader -e -r -a z: cldr.img core.img rofs1.img rofs2.img rofsextension3.img rofs4.img rofs5.img rofs6.img user3.img smr1.img smr2.img -z FFFFFFFFFFFFFFFF 1000 1000 +crash diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/nandtest_load_wdp_autoexec.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/nandtest_load_wdp_autoexec.bat Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,26 @@ +@rem +@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +@rem All rights reserved. +@rem This component and the accompanying materials are made available +@rem under the terms of "Eclipse Public License v1.0" +@rem which accompanies this distribution, and is available +@rem at the URL "http://www.eclipse.org/legal/epl-v10.html". +@rem +@rem Initial Contributors: +@rem Nokia Corporation - initial contribution. +@rem +@rem Contributors: +@rem +@rem Description: +@rem + +z: + +REM Create a primary FAT partition, a Core Image partition, +REM ROFS partitions and a 64MB (0x10000 K) swap file partition +REM Reboot from onboard NAND flash (requires NaviEngine bootloader +REM v1.10 or higher to be installed on the board) + +nandloader -e -r -a z: cldr.img core.img rofs1.img rofs2.img rofsextension3.img rofs4.img rofs5.img rofs6.img user3.img smr1.img smr2.img -z FFFFFFFFFFFFFFFF 1000 1000 -s 10000 + +crash diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/nandtest_shortertest_autoexec.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/nandtest_shortertest_autoexec.bat Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,34 @@ +@rem +@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +@rem All rights reserved. +@rem This component and the accompanying materials are made available +@rem under the terms of "Eclipse Public License v1.0" +@rem which accompanies this distribution, and is available +@rem at the URL "http://www.eclipse.org/legal/epl-v10.html". +@rem +@rem Initial Contributors: +@rem Nokia Corporation - initial contribution. +@rem +@rem Contributors: +@rem +@rem Description: +@rem +z: + +format c: +format d: /e +format d: +format i: +format j: +rem demand paging tests (which may do nothing on non-paging ROMs): +runtests nanddemandpaginge32tests.bat -st -t 20 -c + +format c: +format d: /e +format d: +format i: +format j: +runtests f32test.auto.bat -d i -st -t 45 -c +runtests rofs.auto.bat -d z -t 15 -p -c + + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/nandtest_test_autoexec.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/nandtest_test_autoexec.bat Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,45 @@ +@rem +@rem Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +@rem All rights reserved. +@rem This component and the accompanying materials are made available +@rem under the terms of "Eclipse Public License v1.0" +@rem which accompanies this distribution, and is available +@rem at the URL "http://www.eclipse.org/legal/epl-v10.html". +@rem +@rem Initial Contributors: +@rem Nokia Corporation - initial contribution. +@rem +@rem Contributors: +@rem +@rem Description: +@rem + +trace on 65 +z: +cd test +format c: +format d: /e +format d: +format i: +runtests e32test.auto.bat -st -t 20 -c +format c: +format d: /e +format d: +format i: +runtests loader.auto.bat -st -t 90 -c +format c: +format d: /e +format d: +format i: +runtests f32test.auto.bat -d c -st -t 30 -c +format c: +format d: /e +format d: +format i: +runtests f32test.auto.bat -d d -st -t 90 -c +format c: +format d: /e +format d: +format i: +runtests f32test.auto.bat -d i -st -t 45 -c +runtests rofs.auto.bat -d z -t 15 -p -c diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/pci/d_pci.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/pci/d_pci.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,880 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Device-driver for naviEngine PCI testing +* +*/ + + +#include +#include +#include +#include +#include +#include "allocator.h" +#include "pci-ne.h" +#include "pci_priv.h" +#include +#include "t_pci.h" +#include "../../naviengine_assp/naviengine_pci.h" + +#define TEST(X) __NK_ASSERT_ALWAYS(X) +#define TEST_KERRNONE(X) if((X) !=KErrNone) {\ + Kern::Printf("Assertion Failed X=%d", (X)); FAULT();} + +#define FUNC_LOG() __KTRACE_OPT(KPCI, Kern::Printf(__PRETTY_FUNCTION__)) + + +void TestAllocator(); + +/** +So that the test app can get notification +when PCI DChunks' cleanup operation has run +we will replace their cleanup object with this +one, which will call the original object's destroy +function as well completing a notification +*/ +class TPciCleanupWrapper : public TChunkCleanup + { +public: + + ~TPciCleanupWrapper() + { + delete iOriginal; + Kern::DestroyClientRequest(iClientRequest); + iClient->Close(NULL); + } + + static TPciCleanupWrapper* Create(TRequestStatus* aRequestStatus) + { + __KTRACE_OPT(KPCI, Kern::Printf("TPciCleanupWrapper::Create aRequestStatus=0x%08x", aRequestStatus)); + TClientRequest* request = NULL; + TInt r = Kern::CreateClientRequest(request); + if(r != KErrNone) + { + __KTRACE_OPT(KPCI, Kern::Printf("TPciCleanupWrapper::Create Failed to create client request r=%d", r)); + return NULL; + } + + r = request->SetStatus(aRequestStatus); + if(r != KErrNone) + { + __KTRACE_OPT(KPCI, Kern::Printf("TPciCleanupWrapper::Create Failed to set status r=%d", r)); + Kern::DestroyClientRequest(request); + return NULL; + } + + return new TPciCleanupWrapper(request); + } + + /** + Insert the cleanup object into aChunk, remembering + the original one + + @param aChunk a chunk known to have TChunkCleanup derived cleanup object + */ + void Insert(DChunk* aChunk) + { + __KTRACE_OPT(KPCI, Kern::Printf("TPciCleanupWrapper::Insert aChunk=0x%08x", aChunk)); + __NK_ASSERT_DEBUG(aChunk); + __KTRACE_OPT(KPCI, Kern::Printf("TPciCleanupWrapper replace 0x%08x with 0x%08x", aChunk->iDestroyedDfc, this)); + iOriginal = static_cast(aChunk->iDestroyedDfc); + + __NK_ASSERT_DEBUG(iOriginal); + aChunk->iDestroyedDfc = this; + } + + /** + Run the original object's destroy method + then notify client + */ + void Destroy() + { + __KTRACE_OPT(KPCI, Kern::Printf("TPciCleanupWrapper::Destroy\n")); + iOriginal->Destroy(); + + __NK_ASSERT_ALWAYS(iClientRequest->IsReady()); + Kern::QueueRequestComplete(iClient, iClientRequest, KErrNone); + } + +private: + TPciCleanupWrapper(TClientRequest* aRequest) + :TChunkCleanup(), iOriginal(NULL), iClientRequest(aRequest), iClient(&Kern::CurrentThread()) + { + __ASSERT_CRITICAL; + iClient->Open(); //don't allow thread object to be destroyed before we signal + } + + + TChunkCleanup* iOriginal; + TClientRequest* iClientRequest; + DThread* const iClient; + }; + + + + +//This information will come from the pci driver +//if this code is ever made generic +TPciTestInfo KTestInfo = + { + TPciDevice(0x1033, 0x35, 0), + TPciTestInfo::TAddrSpaceTest(0, 0x00351033, 0), + TPciTestInfo::TAddrSpaceTest(KPciBar0, 0, 0xFFF), + 0, + TPciTestInfo::TAddrSpaceTest(0x34, 0x2EDF, 0), + TPciTestInfo::TAddrSpaceTest(0x20, 0, 0xF), + KNeBridgeNumberOfBars + }; + +/** +Class for a DChunk to remove a DPlatHwChunk chunk +*/ +class TPciPlatChunkCleanup : public TChunkCleanup + { +public: + TPciPlatChunkCleanup(TInt aPciFunction, DPlatChunkHw* aPciPlatChunk); + virtual void Destroy(); +public: + TInt iPciFunction; + DPlatChunkHw* iPciChunk; + }; + +TPciPlatChunkCleanup::TPciPlatChunkCleanup(TInt aPciFunction, DPlatChunkHw* aPciPlatChunk) + : TChunkCleanup(), iPciFunction(aPciFunction), iPciChunk(aPciPlatChunk) + { + } + +void TPciPlatChunkCleanup::Destroy() + { + __KTRACE_OPT(KPCI, Kern::Printf("SHAREDCHUNK ChunkDestroyed DFC\n")); + TInt r = Pci::RemoveChunk(iPciFunction, iPciChunk); + __NK_ASSERT_ALWAYS(r==KErrNone); + } + +/** +Cleanup class to remove the mapping for an externally +mapped chunk +*/ +class TPciMappedChunkCleanup : public TChunkCleanup + { +public: + TPciMappedChunkCleanup (TInt aPciFunction,TUint32 aPhysicalAddress); + virtual void Destroy(); +public: + TInt iPciFunction; + TUint32 iPhysicalAddress; + }; + +TPciMappedChunkCleanup::TPciMappedChunkCleanup(TInt aPciFunction,TUint32 aPhysicalAddress) + : TChunkCleanup(), iPciFunction(aPciFunction),iPhysicalAddress(aPhysicalAddress) + { + } + +void TPciMappedChunkCleanup::Destroy() + { + //remove mapping + TInt r = Pci::RemoveMapping(iPciFunction, iPhysicalAddress); + __NK_ASSERT_ALWAYS(r==KErrNone); + __KTRACE_OPT(KPCI, Kern::Printf("MAPPING REMOVED ChunkDestroyed DFC\n")); + } + +class DPciTestChannel : public DLogicalChannelBase + { +public: + DPciTestChannel(); + virtual ~DPciTestChannel(); + TInt DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); + virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2); + +private: + TInt OpenPciDChunk(TUint32& aPciAddr,TInt aPciChunkSize, TRequestStatus* aStatus); + TInt OpenPciPlatHwChunk(TUint32& aPciAddr,TInt aPciChunkSize, TRequestStatus* aStatus); + TInt OpenPciMappedChunk(TUint32& aPciAddr,TInt aPciChunkSize, TRequestStatus* aStatus); + TInt CreateSharedChunk(TInt aPciChunkSize, TUint32 aAttributes, DChunk*& aChunk, TLinAddr& aVirt, TPhysAddr& aPhysicalAddress); + TInt OpenPciWindowChunk(); + void RunUnitTests(); + +private: + const TPciTestInfo& iTestInfo; + TInt iFunction; ///< PCI function number this channel is associated with + }; + +DPciTestChannel::DPciTestChannel() + : iTestInfo(KTestInfo), iFunction(-1) + { + FUNC_LOG(); + } + +DPciTestChannel::~DPciTestChannel() + { + FUNC_LOG(); + } + +TInt DPciTestChannel::DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer) + { + if(aInfo == NULL) + return KErrNone; //Not a device specific channel + + TPciDevice dev; + TPckg devPckg(dev); + TInt r = Kern::ThreadDesRead(&Kern::CurrentThread(), aInfo, devPckg, 0, KChunkShiftBy0); + if(r != KErrNone) + return r; + + NKern::ThreadEnterCS(); + RArray indicies; + r = Pci::Probe(indicies, dev.iVendorId, dev.iDeviceId); + + if((KErrNone == r) && (dev.iInstance < indicies.Count())) + { + iFunction = indicies[dev.iInstance]; + } + else + { + r = KErrNotFound; + } + + indicies.Close(); + NKern::ThreadLeaveCS(); + return r; + } + +TInt DPciTestChannel::Request(TInt aFunction, TAny* a1, TAny* a2) + { + switch (aFunction) + { + case EGetTestInfo: + { + TDes8& dest(*(TDes8*)a1); + TPckgC info(iTestInfo); + Kern::KUDesPut(dest, info); + return KErrNone; + } + case EAccessConfigSpace: + { + TPckgBuf pckg; + Kern::KUDesGet(pckg, *reinterpret_cast(a1)); + + TAddrSpace* configSpace = Pci::GetConfigSpace(iFunction); + if(configSpace == NULL) + { + Kern::PanicCurrentThread(KPciTest, KErrGeneral); + return KErrGeneral; + } + return pckg().KRun(*configSpace); + } + case EAccessMemorySpace: + { + TPckgBuf pckg; + Kern::KUDesGet(pckg, *reinterpret_cast(a1)); + + TAddrSpace* memSpace = Pci::GetMemorySpace(iFunction, pckg().BarIndex()); + if(memSpace == NULL) + { + Kern::PanicCurrentThread(KPciTest, KErrGeneral); + return KErrGeneral; + } + return pckg().KRun(*memSpace); + } + case EOpenPciWindowChunk: + { + TInt rHandle = 0; + rHandle = OpenPciWindowChunk(); + return rHandle; + } + case EOpenPciDChunk: //Fall-through + case EOpenPciPlatHwChunk: + case EOpenPciMappedChunk: + { + TPckgBuf pckg; + Kern::KUDesGet(pckg, *reinterpret_cast(a1)); + + TUint32 pciAddr; + TInt rHandle = 0; + switch (aFunction) + { + case EOpenPciDChunk: + { + rHandle = OpenPciDChunk(pciAddr, pckg().iSize, pckg().iStatus); + break; + } + case EOpenPciPlatHwChunk: + { + rHandle = OpenPciPlatHwChunk(pciAddr, pckg().iSize, pckg().iStatus); + break; + } + case EOpenPciMappedChunk: + { + rHandle = OpenPciMappedChunk(pciAddr, pckg().iSize, pckg().iStatus); + break; + } + default: + { + FAULT(); + } + } + //write back PCI address to user + umemput(pckg().iPciAddress,&pciAddr,sizeof(pciAddr)); + return rHandle; + } + case ERunUnitTests: + { + RunUnitTests(); + return KErrNone; + } + default: + return KErrNotSupported; + } + } + +/** +This function runs tests for the address allocator +*/ +void DPciTestChannel::RunUnitTests() +{ + // Enter critical section + NKern::ThreadEnterCS(); + + TestAllocator(); + + // Finished + NKern::ThreadLeaveCS(); +} + + +/** +This function creates and opens a PCI DChunk and returns the PCI addresss +@param aPciAddr on return contains the pci address +@param aPciChunkSize contains the size of the PCI DChunk which is to be created +*/ +TInt DPciTestChannel::OpenPciDChunk(TUint32& aPciAddr,TInt aPciChunkSize, TRequestStatus* aStatus) +{ + //Chunk Attributes + TChunkCreateInfo aInfo; + aInfo.iType = TChunkCreateInfo::ESharedKernelMultiple; + aInfo.iMapAttr = EMapAttrSupRw|EMapAttrFullyBlocking; + aInfo.iOwnsMemory = EFalse; // We'll be using our own devices memory + + DChunk* pciChunk; + pciChunk=NULL; + + // Enter critical section + NKern::ThreadEnterCS(); + + //Create DChunk + TInt r = Pci::CreateChunk(iFunction, pciChunk, aInfo,0,aPciChunkSize,aPciAddr); + if(r!=KErrNone) + { + // Failed to create DChunk + __KTRACE_OPT(KPCI,Kern::Printf("Failed to create DChunk: Error code is=%d", r) ); + NKern::ThreadLeaveCS(); // Finished + return r; + } + else + { + TInt rHandle = KErrGeneral; + if(aStatus) + { + TPciCleanupWrapper* wrapper = TPciCleanupWrapper::Create(aStatus); + if(wrapper == NULL) + { + __KTRACE_OPT(KPCI,Kern::Printf("Creation of TPciCleanupWrapper failed")); + goto End; + } + wrapper->Insert(pciChunk); + } + + __KTRACE_OPT(KPCI,Kern::Printf("Created DChunk: PCI_ADDRESS=0x%08x",aPciAddr)); + rHandle = Kern::MakeHandleAndOpen(NULL, pciChunk);//Get DChunk handle + +End: + pciChunk->Close(NULL); // Close DChunk + NKern::ThreadLeaveCS(); // Finished + return rHandle; + } +} + +/** +This function creates and opens a PCI DPlatChunk and returns the PCI addresss. +A DPlatChunk is intially created and then a DChunk is set to point to the same +memory as the DPlatChunk.This is done so that it can be accessed on the user side. +@param aPciAddr on return contains the pci address +@param aPciChunkSize contains the size of the PCI PlatHwChunk which is to be created +*/ +TInt DPciTestChannel::OpenPciPlatHwChunk(TUint32& aPciAddr,TInt aPciChunkSize, TRequestStatus* aStatus) +{ + TUint32 pciPhysicalAddr; + TUint32 pciChunkMapAttr; + TLinAddr pciChunkKernelAddr; + + DPlatChunkHw* pciPlatChunk; + pciPlatChunk=NULL; + + // Enter critical section + NKern::ThreadEnterCS(); + + //Create DPlatChunkHw + TInt r = Pci::CreateChunk(iFunction,pciPlatChunk,aPciChunkSize,(EMapAttrSupRw|EMapAttrFullyBlocking),aPciAddr); + if(r!=KErrNone) + { + // Failed to create DPlatChunkHw + __KTRACE_OPT(KPCI,Kern::Printf("Failed to create DPlatChunkHw chunk: Error code is=%d", r)); + NKern::ThreadLeaveCS(); // Finished + return r; + } + + //Get physical addresss + pciPhysicalAddr = pciPlatChunk->PhysicalAddress(); + + // Create DChunk cleanup object + TPciPlatChunkCleanup* cleanup = new TPciPlatChunkCleanup(iFunction, pciPlatChunk); + if(!cleanup) + { + pciPlatChunk->Close(NULL); //close pciPlatChunk + NKern::ThreadLeaveCS(); + return KErrNoMemory; + } + + //Chunk Attributes for DChunk + TChunkCreateInfo chunkinfo; + chunkinfo.iType = TChunkCreateInfo::ESharedKernelMultiple; + chunkinfo.iMaxSize = 0x4000; + chunkinfo.iMapAttr = EMapAttrSupRw|EMapAttrFullyBlocking; // No caching + chunkinfo.iOwnsMemory = EFalse; // Use memory from system's free pool + chunkinfo.iDestroyedDfc = cleanup; + + DChunk* pciDChunk; + + //Create DChunk + r = Kern::ChunkCreate(chunkinfo, pciDChunk, pciChunkKernelAddr, pciChunkMapAttr); + if(r!=KErrNone) + { + pciPlatChunk->Close(NULL); //close pciPlatChunk + delete cleanup; + NKern::ThreadLeaveCS(); + return r; + } + + pciPlatChunk=NULL; // pciDChunk now owns chunk + + if(aStatus) + { + TPciCleanupWrapper* wrapper = TPciCleanupWrapper::Create(aStatus); + if(wrapper == NULL) + { + pciDChunk->Close(NULL); // Close pciDChunk + NKern::ThreadLeaveCS(); // Finished + return KErrGeneral; + } + wrapper->Insert(pciDChunk); + } + + //Commit memory to a DChunk using DPlatChunkHw physical address + r = Kern::ChunkCommitPhysical(pciDChunk,0,aPciChunkSize,pciPhysicalAddr); + if(r!=KErrNone) + { + // Failed to commit memory + Kern::Printf("Commit failed: Error code is=%d", r); + __KTRACE_OPT(KPCI,Kern::Printf("Commit failed: Error code is=%d", r)); + + // Close chunk, which will then get deleted at some point + Kern::ChunkClose(pciDChunk); + NKern::ThreadLeaveCS(); + return r; + } + + //Close pciPlatChunk using pciDChunk as pciDChunk now owns it + const TInt rHandle = Kern::MakeHandleAndOpen(NULL, pciDChunk); //Get DChunk handle + pciDChunk->Close(NULL); // Close pciDChunk + NKern::ThreadLeaveCS(); // Finished + return rHandle; +} + +/** +This function creates and opens a PCI mapped DChunk and returns the PCI addresss +@param aPciAddr on return contains the pci address +@param aPciChunkSize contains the size of the PCI DChunk which is to be created +*/ +TInt DPciTestChannel::OpenPciMappedChunk(TUint32& aPciAddr,TInt aPciChunkSize, TRequestStatus* aStatus) +{ + TLinAddr virt=NULL; + TPhysAddr physicalAddress=NULL; + DChunk* pciChunk=NULL; + TUint32 pciAttributes=EMapAttrSupRw|EMapAttrFullyBlocking; + + // Enter critical section + NKern::ThreadEnterCS(); + + //create DChunk + TInt r = CreateSharedChunk(aPciChunkSize, pciAttributes, pciChunk, virt, physicalAddress); + if(r!=KErrNone) + { + __KTRACE_OPT(KPCI,Kern::Printf("Create shared Chunk failed: Error code is=%d", r)); + return r; + } + + __NK_ASSERT_ALWAYS(pciChunk); + + //create mapping + r=Pci::CreateMapping(iFunction, physicalAddress, aPciChunkSize, aPciAddr); + if(r!=KErrNone) + { + pciChunk->Close(NULL); + __KTRACE_OPT(KPCI,Kern::Printf("Create mapping failed: Error code is=%d", r)); + return r; + } + + + // Create DChunk cleanup object + TPciMappedChunkCleanup* cleanup = new TPciMappedChunkCleanup(iFunction, physicalAddress); + if(!cleanup) + { + pciChunk->Close(NULL); + NKern::ThreadLeaveCS(); + return KErrNoMemory; + } + + //must add the cleanup dfc to the chunk after creation + //since the cleanup parameters aren't known + //till after creating it and allocating memory to it + pciChunk->iDestroyedDfc = cleanup; + + if(aStatus) + { + TPciCleanupWrapper* wrapper = TPciCleanupWrapper::Create(aStatus); + if(wrapper == NULL) + { + pciChunk->Close(NULL); // Close pciDChunk + NKern::ThreadLeaveCS(); + return KErrGeneral; + } + wrapper->Insert(pciChunk); + } + + //Get DChunk handle + const TInt rHandle = Kern::MakeHandleAndOpen(NULL, pciChunk); + + // Close DChunk + pciChunk->Close(NULL); + + // Finished + NKern::ThreadLeaveCS(); + return rHandle; +} + +/** +This function creates and opens a PCI Window Chunk and returns the PCI Window addresss +@param aPciChunkSize contains the size of the PCI Window DChunk which is to be created +*/ +TInt DPciTestChannel::OpenPciWindowChunk() +{ + TUint32 pciChunkMapAttr; + TLinAddr pciChunkKernelAddr=NULL; + DChunk* pciWindowChunk=NULL; + + //Chunk Attributes for DChunk + TChunkCreateInfo chunkinfo; + chunkinfo.iType = TChunkCreateInfo::ESharedKernelMultiple; + chunkinfo.iMaxSize = 0x2000; + chunkinfo.iMapAttr = EMapAttrSupRw|EMapAttrFullyBlocking; // No caching + chunkinfo.iOwnsMemory = EFalse; // Use memory from system's free pool + + // Enter critical section + NKern::ThreadEnterCS(); + + //Create shared chunk for PCI window + TInt r = Kern::ChunkCreate(chunkinfo, pciWindowChunk, pciChunkKernelAddr, pciChunkMapAttr); + if(r!=KErrNone) + { + // Failed to create DChunk + __KTRACE_OPT(KPCI,Kern::Printf("Failed to create DChunk: Error code is=%d", r) ); + NKern::ThreadLeaveCS(); + return r; + } + + //This address is PSL specific. This will have to be changed + //if d_pci.cpp is ever made generic + TUint32 pciPhysicalAddr = KHwUSBHPhys; // Internal PCI window address + + //Commit memory to a DChunk using Internal PCI window address + r = Kern::ChunkCommitPhysical(pciWindowChunk,0,KHwUSBHInternalPciWindowSize, pciPhysicalAddr); + if(r!=KErrNone) + { + // Failed to commit memory + Kern::Printf("Commit failed: Error code is=%d", r); + __KTRACE_OPT(KPCI,Kern::Printf("Commit failed: Error code is=%d", r)); + + // Close chunk, which will then get deleted at some point + Kern::ChunkClose(pciWindowChunk); + NKern::ThreadLeaveCS(); + return r; + } + + //Close pciPlatChunk using pciDChunk as pciDChunk now owns it + const TInt rHandle = Kern::MakeHandleAndOpen(NULL, pciWindowChunk); //Get PCI Window DChunk handle + pciWindowChunk->Close(NULL); // Close pci window chunk + NKern::ThreadLeaveCS(); // Finished + return rHandle; +} + +/** +This function creates and opens a shared chunk. The chunk is then commited to a contiguous memory +@param aPciChunkSize contains the size of the PCI DChunk which is to be created +@param aAttributes on return, this is set to the mmu mapping attributes used for the chunk +@param aChunk on return, a reference to the shared chunk +@param aVirt on return, this is set to the virtual address shared chunk +@param aPhysicalAddress on return, this is set to the physical address of the first page of memory + which was committed. +*/ +TInt DPciTestChannel::CreateSharedChunk(TInt aPciChunkSize, TUint32 aAttributes, DChunk*& aChunk, TLinAddr& aVirt, TPhysAddr& aPhysicalAddress) +{ + __NK_ASSERT_DEBUG(aChunk==NULL); + aPciChunkSize = Kern::RoundToPageSize(aPciChunkSize); + DChunk* pC=NULL; + + // Enter critical section + NKern::ThreadEnterCS(); + + //Chunk Attributes for DChunk + TChunkCreateInfo info; + info.iType=TChunkCreateInfo::ESharedKernelSingle; + info.iMaxSize=aPciChunkSize; + info.iMapAttr=aAttributes; + info.iOwnsMemory=ETrue; + + //Create DChunk + TInt r=Kern::ChunkCreate(info, pC, aVirt, aAttributes); + if(r!=KErrNone) + { + NKern::ThreadLeaveCS(); + return r; + } + //Commit DChunk to Contiguous memory + r = Kern::ChunkCommitContiguous(pC, 0, aPciChunkSize, aPhysicalAddress); + if(r==KErrNone) + { + aChunk=pC; + } + else + { + Kern::ChunkClose(pC); + __KTRACE_OPT(KPCI,Kern::Printf("Commit DChunk to Contiguous memory Failed : Error code is=%d",r)); + return r; + } + + NKern::ThreadLeaveCS(); // Finished + __KTRACE_OPT(KPCI, Kern::Printf("Created SC: size=0x%08x, virtual= 0x%08x, phys=0x%08x", aPciChunkSize, aVirt, aPhysicalAddress)); + return r; +} + +class DPciDevice : public DLogicalDevice + { +public: + DPciDevice(); + ~DPciDevice(); + TInt Install(); + void GetCaps(TDes8& aDes) const; + TInt Create(DLogicalChannelBase*& aChannel); + }; + +DPciDevice::DPciDevice() + { + FUNC_LOG(); + } + +DPciDevice::~DPciDevice() + { + FUNC_LOG(); + } + +TInt DPciDevice::Install() + { + return SetName(&KPciLddFactory); + } + +void DPciDevice::GetCaps(TDes8&) const + { + } + +TInt DPciDevice::Create(DLogicalChannelBase*& aChannel) + { + aChannel = new DPciTestChannel; + return aChannel ? KErrNone : KErrNoMemory; + } + +/**************************************** +TUserPciSpace +*/ + +/** +Decides what action to run based on contents of class +*/ +TUint TUserPciSpace::KRun(TAddrSpace& aAddrSp) + { + + //this could be reworked as a function pointer + //table, but this might be clearer + switch(iBitWidth) + { + case 8: + { + switch(iOperation) + { + case ERead: + { + return aAddrSp.Read8(iOffset); + } + case EWrite: + { + aAddrSp.Write8(iOffset, iWriteValue); + return KErrNone; + } + case EModify: + { + aAddrSp.Modify8(iOffset, iClearMask, iSetMask); + return KErrNone; + } + default: + { + Kern::PanicCurrentThread(KPciTest, KErrNotReady); + } + } + } + case 16: + { + switch(iOperation) + { + case ERead: + { + return aAddrSp.Read16(iOffset); + } + case EWrite: + { + aAddrSp.Write16(iOffset, iWriteValue); + return KErrNone; + } + case EModify: + { + aAddrSp.Modify16(iOffset, iClearMask, iSetMask); + return KErrNone; + } + default: + { + Kern::PanicCurrentThread(KPciTest, KErrNotReady); + } + } + } + case 32: + { + switch(iOperation) + { + case ERead: + { + return aAddrSp.Read32(iOffset); + } + case EWrite: + { + aAddrSp.Write32(iOffset, iWriteValue); + return KErrNone; + } + case EModify: + { + aAddrSp.Modify32(iOffset, iClearMask, iSetMask); + return KErrNone; + } + default: + { + Kern::PanicCurrentThread(KPciTest, KErrNotReady); + } + } + } + default: + { + Kern::PanicCurrentThread(KPciTest, KErrArgument); + } + + } + + //unreachable return + return KMaxTUint; + } + +//stub implementation for kernel side +TUint TUserConfigSpace::Call() + { + FAULT(); + return 0; + } + +TUserPciSpace* TUserConfigSpace::Clone() const + { + FAULT(); + return 0; + } + +//stub implementation for kernel side +TUint TUserMemorySpace::Call() + { + FAULT(); + return 0; + } + +TUserPciSpace* TUserMemorySpace::Clone() const + { + FAULT(); + return 0; + } + +void TestAllocator() + { + __KTRACE_OPT(KPCI, Kern::Printf("Testing address allocator")); + TAddressAllocator allocator(0x80000000); //2 GB + TLinAddr rcvdAddr=NULL; + TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x10) ); + TEST(0x0 ==rcvdAddr); + TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x100) ); + TEST(0x100 ==rcvdAddr); + TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x10) ); + TEST(0x10 ==rcvdAddr); + TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x10) ); + TEST(0x20 ==rcvdAddr); + //test deallocating + TEST_KERRNONE(allocator.DeAllocate(0x0)); + TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x10) ); + TEST(0x000 ==rcvdAddr); + + TEST_KERRNONE(allocator.DeAllocate(0x100)); + TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x100) ); + TEST(0x100 ==rcvdAddr); + + TEST_KERRNONE(allocator.DeAllocate(0x10)); + TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x10) ); + TEST(0x10 ==rcvdAddr); + + TEST_KERRNONE(allocator.DeAllocate(0x20)); + TEST_KERRNONE(allocator.Allocate(rcvdAddr,0x20) ); + TEST(0x20 ==rcvdAddr); + + TEST(allocator.DeAllocate(0x40)==KErrNotFound); + TEST_KERRNONE(allocator.DeAllocate(0x100)); + TEST_KERRNONE(allocator.DeAllocate(0x20)); + TEST_KERRNONE(allocator.DeAllocate(0x0)); + TEST_KERRNONE(allocator.DeAllocate(0x10)); + } + + +DECLARE_STANDARD_LDD() + { + return new DPciDevice; + } diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/pci/t_pci.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/pci/t_pci.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,825 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* memory space. +* - RPciChunk which is derived from and RChunk and corresponds to +* a kernel-side DChunk, which in turn corresponds to a PCI chunk or +* buffer. The test driver uses these for all PCI chunk types (a +* "wrapper" DChunk is used to map the memory of a PCI DPlatHwChunk +* to user side). +* +*/ + + +#include +#define __E32TEST_EXTENSION__ +#include +#include "t_pci.h" +#include + +class RPci; +/** +Extends RChunk to hold the PCI address +associated with a chunk. +*/ +class RPciChunk: public RChunk + { +public: + TUint PciBase() + { + return iPciBaseAddr; + } + + /** + Return the PCI accessible size + */ + TInt Size() const + { + return iPciSize; + } + +private: + friend class RPci; + TUint iPciBaseAddr; + TInt iPciSize; //size of the region mapped into PCI + }; + +typedef TInt (RPci::*ChunkOpenFn)(RPciChunk&, TInt, TRequestStatus*); + +class RPci : public RBusLogicalChannel + { +public: + TInt Open(); + TInt GetTestInfo(TPciTestInfo& aTestInfo); + + TInt Open(const TPciDevice&); + + TUint AccessConfigSpace(const TUserConfigSpace& aCs); + TUint AccessMemorySpace(const TUserMemorySpace& aMs); + TInt OpenPciDChunk(RPciChunk& aPciChunk,TInt aPciChunkSize, TRequestStatus* aStatus=0); + TInt OpenPciPlatHwChunk(RPciChunk& aPciHwChunk,TInt aPciChunkSize, TRequestStatus* aStatus=0); + TInt OpenPciMappedChunk(RPciChunk& aPciMappedChunk,TInt aPciChunkSize, TRequestStatus* aStatus=0); + TInt OpenPciWindowChunk(RChunk& aPciWindowChunk); + TInt RunUnitTests(); +private: + TInt DoOpenPciChunk(RPciChunk& aPciChunk, TInt aPciChunkSize, TPciTestCmd aCmd, TRequestStatus* aStatus); + }; + +inline TInt RPci::Open() + { + return DoCreate(KPciLddFactory, TVersion(), KNullUnit, NULL, NULL); + } + +inline TInt RPci::Open(const TPciDevice& aDevice) + { + TPckgC devicePkg(aDevice); + return DoCreate(KPciLddFactory, TVersion(), KNullUnit, NULL, &devicePkg); + } + +inline TInt RPci::GetTestInfo(TPciTestInfo& aTestInfo) + { + TPckg info(aTestInfo); + return DoControl(EGetTestInfo, &info); + } + +inline TInt RPci::RunUnitTests() + { + return DoControl(ERunUnitTests); + } + +TUint RPci::AccessConfigSpace(const TUserConfigSpace& aCs) + { + TPckgC pkg(aCs); + return DoControl(EAccessConfigSpace, &pkg); + } + +TUint RPci::AccessMemorySpace(const TUserMemorySpace& aMs) + { + TPckgC pkg(aMs); + return DoControl(EAccessMemorySpace, &pkg); + } + +TInt RPci::OpenPciDChunk(RPciChunk& aPciChunk,TInt aPciChunkSize, TRequestStatus* aStatus) + { + return DoOpenPciChunk(aPciChunk, aPciChunkSize, EOpenPciDChunk, aStatus); + } + +TInt RPci::OpenPciPlatHwChunk(RPciChunk& aPciHwChunk,TInt aPciChunkSize, TRequestStatus* aStatus) + { + return DoOpenPciChunk(aPciHwChunk, aPciChunkSize, EOpenPciPlatHwChunk, aStatus); + } + +TInt RPci::OpenPciMappedChunk(RPciChunk& aPciMappedChunk,TInt aPciChunkSize, TRequestStatus* aStatus) + { + return DoOpenPciChunk(aPciMappedChunk, aPciChunkSize, EOpenPciMappedChunk, aStatus); + } + +TInt RPci::OpenPciWindowChunk(RChunk& aPciWindowChunk) + { + TUint chunkHandle = DoControl(EOpenPciWindowChunk); + return aPciWindowChunk.SetReturnedHandle(chunkHandle); + } + +TInt RPci::DoOpenPciChunk(RPciChunk& aPciChunk, TInt aPciChunkSize, TPciTestCmd aCmd, TRequestStatus* aStatus) + { + const TInt constPciChunkSize = aPciChunkSize; + TPciChunkCreateInfo info(constPciChunkSize, aPciChunk.iPciBaseAddr, aStatus); + TPckgC pkg(info); + + TUint chunkHandle = DoControl(aCmd, &pkg); + + const TInt r = aPciChunk.SetReturnedHandle(chunkHandle); + if(r == KErrNone) + { + aPciChunk.iPciSize = constPciChunkSize; + } + return r; + } + +TUserPciSpace::TUserPciSpace(RPci& aPci) + :iPci(&aPci) + {} + +TUserConfigSpace::TUserConfigSpace(RPci& aPci) + :TUserPciSpace(aPci) + {} + +TUint TUserConfigSpace::Call() + { + return iPci->AccessConfigSpace(*this); + } + +TUserPciSpace* TUserConfigSpace::Clone() const + { + return new TUserConfigSpace(*this); + } + +TUserMemorySpace::TUserMemorySpace(RPci& aPci, TInt aBarIndex) + :TUserPciSpace(aPci), iBarIndex(aBarIndex) + {} + +TUint TUserMemorySpace::Call() + { + return iPci->AccessMemorySpace(*this); + } + +TUserPciSpace* TUserMemorySpace::Clone() const + { + return new TUserMemorySpace(*this); + } + +/** +Test address allocator +*/ +TInt TestRunPciUnitTest(RPci& pci) + { + return pci.RunUnitTests(); + } + + +/** +Read from a defined address in memory or config space, compare against expected values. +8,16, and 32 bit accesses performed. + +@param aSpace Object gving access to either the config or memory space of a PCI device +@param aInfo Contains the address and expected value of a dword +*/ +void TestReadAddressSpace(TUserPciSpace& aSpace, const TPciTestInfo::TAddrSpaceTest& aInfo, RTest& test, TBool aVerbose=EFalse) + { + const TUint os = aInfo.iOffset; + //Iterate over different widths, and possible + //subfields of 32 bit word + for(TInt bitWidth=32; bitWidth>=8; bitWidth>>=1) + { + const TInt numberOfFields = (32/bitWidth); + for(TInt i=0; i< numberOfFields; i++) + { + const TInt extraByteOffset = i * (bitWidth >> 3); + const TInt byteOffset = os + extraByteOffset; + if(aVerbose) + test.Printf(_L("Access bitWidth=%d byte offset=%d\n"), bitWidth, byteOffset); + + const TUint expected = aInfo.Expected(bitWidth, byteOffset); + const TUint read = aSpace.Read(bitWidth, byteOffset); + if(aVerbose) + test.Printf(_L("expect 0x%08x, read 0x%08x\n"), expected, read); + test_Equal(expected, read); + } + } + } + +/** +Verify writes and modifications to a defined address in memory or config space. 8,16, and 32 bit +accesses performed. + +@param aSpace Object gving access to either the config or memory space of a PCI device +@param aInfo Contains the address of a (at least partially) writable dword +*/ +void TestWriteAddressSpace(TUserPciSpace& aSpace, TPciTestInfo::TAddrSpaceTest& aInfo, RTest& test, TBool aVerbose=EFalse) + { + const TUint original = aSpace.Read(32, aInfo.iOffset); + const TUint os = aInfo.iOffset; + TUint mask = ~aInfo.iReadOnlyMask; + + //The pattern will be truncated when used with bit widths + //less than 32. + const TUint initPattern = 0xFFFFFFFF; + + for(TInt bitWidth=32; bitWidth>=8; bitWidth>>=1) + { + const TUint pattern = initPattern >> (32-bitWidth); + const TInt numberOfFields = (32/bitWidth); + for(TInt i=0; i< numberOfFields; i++) + { + const TInt extraByteOffset = i * (bitWidth >> 3); + const TInt byteOffset = os + extraByteOffset; + if(aVerbose) + test.Printf(_L("Access bitWidth=%d byte offset=%d\n"), bitWidth, byteOffset); + //the full dword we expect + //currently assume that the unwritable bits will be 0 + const TUint writeExpect = (pattern << (bitWidth * i) ) & mask; + const TUint clearExpect = 0; + + //do write followed by clear + const TUint expect[] = {writeExpect, clearExpect}; + const TUint write[] = {pattern, 0}; + for(TInt n = 0; n < 2; n++) + { + aSpace.Write(bitWidth, byteOffset, write[n]); + TUint result = aSpace.Read(32, os); + + if(aVerbose) + test.Printf(_L("wrote 0x%08x, expect 0x%08x, read 0x%08x\n"), + write[n], expect[n], result); + test_Equal(expect[n], result); + } + + //test Modify calls. Set then clear pattern + TUint set[] = {pattern, 0}; + TUint clear[] = {0, pattern}; + + for(TInt m = 0; m < 2; m++) + { + aSpace.Modify(bitWidth, byteOffset, clear[m], set[m]); + TUint result = aSpace.Read(32, os); + + if(aVerbose) + test.Printf(_L("clear 0x%08x, set 0x%08x, expect 0x%08x, read 0x%08x\n"), clear[m], set[m], expect[m], result); + test_Equal(expect[m], result); + } + } + } + + //restore orginal value or we will not be able to access device + aSpace.Write(32, os, original); + } + + +/** +Verify that a PCI DChunk can be opened and closed from user side + +@param pci The RPci object to use +@param test The RTest object to use +@param aPciChunkSize The size of the DChunk which would be created +*/ +void TestOpenAndCloseDChunk(RPci& pci,RTest& test,TInt aPciChunkSize) + { + RPciChunk testPciDChunk; + + // Create and open Chunk + TRequestStatus status; + TInt r = pci.OpenPciDChunk(testPciDChunk,aPciChunkSize, &status); + test_KErrNone(r); + + test(testPciDChunk.IsWritable()); + test(testPciDChunk.IsReadable()); + + test.Printf(_L("PCI Chunk base = 0x%08x\n"), testPciDChunk.Base()); + test.Printf(_L("PCI Chunk size = %d\n"), testPciDChunk.Size()); + test.Printf(_L("PCI Address = 0x%08x\n"), testPciDChunk.PciBase()); + + //Close Chunk + test.Next(_L("Close PCI Chunk handle")); + + RTest::CloseHandleAndWaitForDestruction(testPciDChunk); + User::WaitForRequest(status); + } + +/** +Verify that a PCI PlatHwChunk can be opened and closed from user side + + +@param pci The RPci object to use +@param test The RTest object to use +@param aPciChunkSize The size of the PlatHwChunk which would be created +*/ +void TestOpenAndClosePciPlatHwChunk(RPci& pci,RTest& test,TInt aPciChunkSize) + { + RPciChunk testPciPlatHwChunk; + + // Create and open Chunk + TRequestStatus status; + TInt r = pci.OpenPciPlatHwChunk(testPciPlatHwChunk,aPciChunkSize, &status); + test_KErrNone(r); + + test(testPciPlatHwChunk.IsWritable()); + test(testPciPlatHwChunk.IsReadable()); + + test.Printf(_L("PCI Chunk base = 0x%08x\n"), testPciPlatHwChunk.Base()); + test.Printf(_L("PCI Chunk size = %d\n"), testPciPlatHwChunk.Size()); + test.Printf(_L("PCI Address = 0x%08x\n"), testPciPlatHwChunk.PciBase()); + + //Close Chunk + testPciPlatHwChunk.Close(); + User::WaitForRequest(status); + test.Next(_L("Closed PCI PlatHwChunk handle")); + } + +/** +Verify that pci-mapped DChunk can be opended and closed form user side + +@param pci The RPci object to use +@param test The RTest object to use +@param aPciChunkSize The size of the pci-mapped DChunk which would be created +*/ +void TestPciMapppedChunk(RPci& pci,RTest& test,TInt aPciChunkSize) + { + RPciChunk testPciMappedChunk; + + // Create and open Chunk + TRequestStatus status; + TInt r = pci.OpenPciMappedChunk(testPciMappedChunk,aPciChunkSize, &status); + test_KErrNone(r); + + test(testPciMappedChunk.IsWritable()); + test(testPciMappedChunk.IsReadable()); + + test.Printf(_L("PCI Chunk base = 0x%08x\n"), testPciMappedChunk.Base()); + test.Printf(_L("PCI Chunk size = %d\n"), testPciMappedChunk.Size()); + test.Printf(_L("PCI Address = 0x%08x\n"), testPciMappedChunk.PciBase()); + + //Close Chunk + testPciMappedChunk.Close(); + User::WaitForRequest(status); + test.Next(_L("Closed PCI Mapped Chunk handle")); + } + +/** +Verify that an RChunk can be open to grant access to the internal PCI window from the user side + +@param pci The RPci object to use +@param test The RTest object to use +*/ +void TestPciWindowChunk(RPci& pci,RTest& test) + { + RChunk testPciWindowChunk; + + // Create and open DChunk + TInt r = pci.OpenPciWindowChunk(testPciWindowChunk); + test_KErrNone(r); + + test(testPciWindowChunk.IsWritable()); + test(testPciWindowChunk.IsReadable()); + + test.Printf(_L("PCI Window Chunk base = 0x%08x\n"), testPciWindowChunk.Base()); + test.Printf(_L("PCI Window Chunk size = %d\n"), testPciWindowChunk.Size()); + + //Close Chunk + testPciWindowChunk.Close(); + test.Next(_L("Closed PCI Window Chunk handle")); + } + + +class CPciTest : public CTest + { +protected: + CPciTest(const TDesC& aName, TInt aIterations, RPci& aDevice) + : CTest(aName, aIterations), iDevice(aDevice) + {} + + RPci iDevice; + }; + +/** +Each instance of test will open a chunk, using the function specified in +the template argument, FUNC. + +The total number of chunks that can be opened by all instances is limited +by iMaxCount. + +All intances of the test will hold their chunk open until iMaxCount has +been reached. +*/ +template +class CPciOpenChunkTest : public CPciTest + { +public: + CPciOpenChunkTest(const TDesC& aName, TInt aIterations, RPci& aDevice, + RSemaphore aSemOpen, RSemaphore aSemClose, RFastLock aLock, TInt aMaxCount) + :CPciTest(aName, aIterations, aDevice), + iSemOpen(aSemOpen), iSemClose(aSemClose), iLock(aLock), iMaxCount(aMaxCount) + { + } + + virtual void RunTest() + { + RTest test(iName); + RPciChunk chunk; + + iSemOpen.Wait(); + TRequestStatus status; + const TInt chunkSize = 0x400; + //open chunk by calling FUNC + TInt r = ((iDevice).*(FUNC))(chunk, chunkSize, &status); + test_KErrNone(r); + + iLock.Wait(); + iOpenCount++; + test.Printf(_L("Opened chunk %d\n"), iOpenCount); + if(iOpenCount == iMaxCount) + { + test.Printf(_L("Opened=%d, max=%d: Allow chunks to close\n"), iOpenCount, iMaxCount); + //release all waiting threads + //plus 1 preincrement so this + //thread also passes + iSemClose.Signal(iOpenCount); + iOpenCount = 0; + } + iLock.Signal(); + + + iSemClose.Wait(); + chunk.Close(); + User::WaitForRequest(status); + + // permit another chunk to be opened + iSemOpen.Signal(); + test.Close(); + } + + virtual CTest* Clone() const + { + //make shallow copy + return new CPciOpenChunkTest(*this); + } + + +private: + RSemaphore& iSemOpen; //!< Represents the number of available PCI mappings + RSemaphore& iSemClose; //!< Represents the number of threads waiting to close their chunk + RFastLock& iLock; + static TInt iOpenCount; + const TInt iMaxCount; + }; + +template +TInt CPciOpenChunkTest::iOpenCount = 0; + + +/** +Test which will perform various reads from a PCI address +space (config or memory) and confirm that values are read +as expected +*/ +class CPciAddressSpaceRead : public CPciTest + { +public: + CPciAddressSpaceRead(const TDesC& aName, TInt aIterations, RPci& aDevice, + const TUserPciSpace& aSpace, const TPciTestInfo::TAddrSpaceTest& aInfo) + :CPciTest(aName, aIterations, aDevice), + iAddressSpace(aSpace.Clone()), iSpaceTestInfo(aInfo) + { + } + + CPciAddressSpaceRead(const CPciAddressSpaceRead& aOther) + :CPciTest(aOther)/* TODO-REVIEW have object-sliced aOther - is this ok?*/, + iAddressSpace(aOther.iAddressSpace->Clone()), iSpaceTestInfo(aOther.iSpaceTestInfo) + { + } + + virtual ~CPciAddressSpaceRead() + { + delete iAddressSpace; + } + + virtual void RunTest() + { + __UHEAP_MARK; + RTest test(iName); + TestReadAddressSpace(*iAddressSpace, iSpaceTestInfo, test); + test.Close(); + __UHEAP_MARKEND; + } + + virtual CTest* Clone() const + { + //make shallow copy + return new CPciAddressSpaceRead(*this); + } + +private: + TUserPciSpace* iAddressSpace; + const TPciTestInfo::TAddrSpaceTest& iSpaceTestInfo; + }; + +/** +For aBuffer, test writing to it then reading back from aWindow +then write via window and read back from chunk + +@param test The RTest object to use +@param aBuffer RChunk corresponding to a PCI accessible buffer +@param aWindow RChunk coressponding an appropriate System-to-PCI memory window +It is presumed to start at PCI address 0 +*/ +void DoLoopBackTest(RTest& test, RPciChunk aBuffer, RChunk aWindow) + { + test.Start(_L("Test accessing memory via PCI")); + + TUint8* const bufferBase = aBuffer.Base(); + const TUint bufferSize = aBuffer.Size(); + const TUint bufferPciBase = aBuffer.PciBase(); + + TUint8* const windowBase = aWindow.Base(); + const TUint windowSize = aWindow.Size(); + +#define PRINT(N) RDebug::Printf("%s = 0x%08x (%d)", #N, (N), (N)) + PRINT(bufferBase); + PRINT(bufferSize); + PRINT(bufferPciBase); + + PRINT(windowBase); + PRINT(windowSize); + +#undef PRINT + + //need to check that the end of the buffer + //is within the windowed region + test(bufferPciBase + bufferSize <= windowSize); + TUint8* const bufferBaseWithinWindow = windowBase + bufferPciBase; + + test.Next(_L("write chunk")); + for(TUint i = 0; i < bufferSize; ++i) + { + //each byte will hold its own offset modulo 256 + bufferBase[i] = (TUint8)i; + } + + test.Next(_L("read back via window")); + for(TUint j=0; j < bufferSize; ++j) + { + const TUint8 result = bufferBaseWithinWindow[j]; + test_Equal(j%256, result); + } + + //clear chunk + memclr(bufferBase, bufferSize); + test.Next(_L("write via window")); + for(TUint k=0; k < bufferSize; ++k) + { + //each byte will hold its own offset modulo 256 + bufferBaseWithinWindow[k] = (TUint8)k; + } + + test.Next(_L("read back from chunk")); + for(TUint l=0; l < bufferSize; ++l) + { + const TUint8 result = bufferBase[l]; + test_Equal(l%256, result); + } + + test.End(); + } + +/** +Take care of opening a chunk, running the test and closing +*/ +template +inline void LoopBackTest(RPci& aPci, RTest& test, RChunk& aWindow) + { + RPciChunk pciChunk; + const TInt chunkSize = 0x400; //1k + + //call the specified chunk opening function + TRequestStatus status; + TInt r = ((aPci).*(OPEN_FUNC))(pciChunk, chunkSize, &status); + test_KErrNone(r); + DoLoopBackTest(test, pciChunk, aWindow); + pciChunk.Close(); + User::WaitForRequest(status); + } + +/** +Run the loopback test for the 3 types of buffer supported by the PCI driver. +DChunk +DPlatChunk +Mapped In external memory +*/ +void TestLoopBack(RPci& aPci, RTest& test) + { + test.Next(_L("Open PCI window")); + RChunk window; + + TInt r = aPci.OpenPciWindowChunk(window); + test_KErrNone(r); + + test.Next(_L("DChunk")); + LoopBackTest<&RPci::OpenPciDChunk>(aPci, test, window); + + test.Next(_L("DPlatHwChunk")); + LoopBackTest<&RPci::OpenPciPlatHwChunk>(aPci, test, window); + + test.Next(_L("DChunk (mapped in)")); + LoopBackTest<&RPci::OpenPciMappedChunk>(aPci, test, window); + + window.Close(); + } +#ifndef __VC32__ //visual studio 6 doesn't approve of pointer to member function template parameters +/** +Run the CPciOpenChunkTest for each type of chunk. This function also creates (and destroys) the +necessary semaphores and locks. +CPciOpenChunkTest objects are run in multiple threads using MultipleTestRun(). + +@param aDevice Handle to the test driver +@param test RTest to use. +@param aBufferLimit The maximum number of buffers which can be opened simultaneously +*/ +void TestBufferOpenConcurrency(RPci& aDevice, RTest& test, TInt aBufferLimit) + { + RSemaphore semaphoreOpen; + RSemaphore semaphoreClose; + RFastLock lock; + + TInt r = semaphoreOpen.CreateLocal(aBufferLimit); + test_KErrNone(r); + + r = semaphoreClose.CreateLocal(0); + test_KErrNone(r); + + r = lock.CreateLocal(); + test_KErrNone(r); + + const TInt iterations = 3; + { + test.Printf(_L("Opening %d PCI DChunks in %d threads\n"), aBufferLimit, aBufferLimit); + CPciOpenChunkTest<&RPci::OpenPciDChunk> + dChunkTest(_L("Concurrent-DChunk"), iterations, aDevice, semaphoreOpen, semaphoreClose, lock, aBufferLimit); + + MultipleTestRun(test, dChunkTest, aBufferLimit); + } + + { + test.Printf(_L("Opening %d PCI DPlatHwChunks in %d threads\n"), aBufferLimit, aBufferLimit); + CPciOpenChunkTest<&RPci::OpenPciPlatHwChunk> + platChunkTest(_L("Concurrent-DPlatHwChunk"), iterations, aDevice, semaphoreOpen, semaphoreClose, lock, aBufferLimit); + + MultipleTestRun(test, platChunkTest, aBufferLimit); + } + + { + test.Printf(_L("Opening %d PCI Mapped chunks in %d threads\n"), aBufferLimit, aBufferLimit); + CPciOpenChunkTest<&RPci::OpenPciMappedChunk> + mappedChunkTest(_L("Concurrent-DChunk(mapped)"), iterations, aDevice, semaphoreOpen, semaphoreClose, lock, aBufferLimit); + + MultipleTestRun(test, mappedChunkTest, aBufferLimit); + } + + semaphoreOpen.Close(); + semaphoreClose.Close(); + lock.Close(); + } +#endif + +TInt E32Main() + { + __UHEAP_MARK; + + _LIT(KPci, "PCI"); + RTest test(KPci); + test.Start(_L("Running PCI tests\n")); + + TInt r = User::LoadLogicalDevice(KPciLdd); + + __KHEAP_MARK; + + if(r==KErrNotFound) + { + test.Printf(_L("No PCI system present - skipping test\n")); + return KErrNone; + } + if(r!=KErrNone && r!=KErrAlreadyExists) + { + test_KErrNone(r); + } + + test.Next(_L("Open non-existant device\n")); + RPci device; + TPciDevice unavailable; + r = device.Open(unavailable); + test_Equal(KErrNotFound, r); + + RPci pciInfo; + r = pciInfo.Open(); + test_KErrNone(r); + + test.Next(_L("Get test info from driver\n")); + TPciTestInfo info; + r = pciInfo.GetTestInfo(info); + test_KErrNone(r); + pciInfo.Close(); + + test.Next(_L("Open test device\n")); + r = device.Open(info.iDevice); + test_KErrNone(r); + + test.Next(_L("Run Device Unit Test\n")); + r=TestRunPciUnitTest(device); + test_KErrNone(r); + + test.Next(_L("Read config space\n")); + TUserConfigSpace cs(device); + TestReadAddressSpace(cs, info.iCfgSpaceRead, test); + + test.Next(_L("Write config space\n")); + TestWriteAddressSpace(cs, info.iCfgSpaceWrite, test); + + test.Next(_L("Read memory space\n")); + TUserMemorySpace ms(device, info.iMemSpaceIndex); + TestReadAddressSpace(ms, info.iMemSpaceRead, test); + + test.Next(_L("Modify memory space\n")); + TestWriteAddressSpace(ms, info.iMemSpaceWrite, test); + + { + const TInt addrSpaceThreadCount = 4; + const TInt iterations = 100; + test.Next(_L("Concurrent config space reads")); + CPciAddressSpaceRead cfgSpaceRead(_L("Cfg Space Read"), iterations, device, cs, info.iCfgSpaceRead); + MultipleTestRun(test, cfgSpaceRead, addrSpaceThreadCount); + + test.Next(_L("Concurrent memory space reads")); + CPciAddressSpaceRead memSpaceRead(_L("Memory Space Read"), iterations, device, ms, info.iMemSpaceRead); + MultipleTestRun(test, memSpaceRead, addrSpaceThreadCount); + } + + TInt testDChunkSize = 0x4000; + test.Next(_L("Open and Close DChunks\n")); + TestOpenAndCloseDChunk(device,test,testDChunkSize); + + TInt testDPlatChunkSize = 0x2000; + test.Next(_L("Open and Close PlatHwChunks\n")); + TestOpenAndClosePciPlatHwChunk(device,test,testDPlatChunkSize); + + //TestPciMapppedChunk() fails for sizes greater than 4K. + //The issue is that a block of externally mapped memory must be + //naturally alligned in order to be accessible to the PCI bus (ie + //an 8k buffer would have to start at an address which is a + //multiple of 8k. + // + //Now we could fix this for sure on the kernel side, by making + //sure we only commit correctly aligned memory into the chunk (as + //the pci driver itself does), + //However, by using a 4k chunk, we know this will be on a page + //boundary so the alignment is correct (assuming the page size + //isn't changed). + TInt testMapppedChunkSize = 0x1000; + test.Next(_L("Open and Close Pci Mappped Chunk\n")); + TestPciMapppedChunk(device,test,testMapppedChunkSize); + + test.Next(_L("Open and Close Pci Window Chunk\n")); + TestPciWindowChunk(device,test); + + const TInt numberOfThreads = info.iNumberOfBars; + test.Printf(_L("Open buffers concurrently, max supported = %d\n"), numberOfThreads); +#ifndef __VC32__ + TestBufferOpenConcurrency(device, test, numberOfThreads); +#else + test.Printf(_L("TestBufferOpenConcurrency not implemented for WINS"), numberOfThreads); +#endif + + test.Next(_L("Test loop back")); + TestLoopBack(device, test); + + device.Close(); + __KHEAP_MARKEND; + + r = User::FreeLogicalDevice(KPciLdd); + test_KErrNone(r); + + test.End(); + test.Close(); + + __UHEAP_MARKEND; + return KErrNone; + } + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/pci/t_pci.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/pci/t_pci.h Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,482 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This is the header file for the PCI driver test. +* +*/ + + +#ifndef __TPCI_TEST_H +#define __TPCI_TEST_H + +#ifndef __KERNEL_MODE__ +#define __E32TEST_EXTENSION__ +#include + +// Following contents are carbon copy of \os\kernelhwsrv\kerneltest\e32test\misc\test_thread.h +#include +#include +#include +#include +#include +#include +#include +#include + + +_LIT(KPciPanicCat, "test_thread.h"); + +static const TInt KPciHeapSize=0x2000; + +enum TPciPanicCode + { + EThreadCreateFailed + }; + +/** +A utility class for running functions in other threads/processes +*/ +class TTestRemote + { +public: + virtual TInt WaitForExitL() = 0; + virtual ~TTestRemote() + {} + + virtual void Rendezvous(TRequestStatus& aStatus) = 0; + +protected: + TTestRemote() + {} + + static TInt RunFunctor(TAny* aFunctor) + { + TFunctor& functor = *(TFunctor*)aFunctor; + functor(); + return KErrNone; + } + + TRequestStatus iLogonStatus; + static TInt iCount; + }; +TInt TTestRemote::iCount=0; + +class TTestThread : public TTestRemote + { +public: + TTestThread(const TDesC& aName, TThreadFunction aFn, TAny* aData, TBool aAutoResume=ETrue) + { + Init(aName, aFn, aData, aAutoResume); + } + + /** + Run aFunctor in another thread + */ + TTestThread(const TDesC& aName, TFunctor& aFunctor, TBool aAutoResume=ETrue) + { + Init(aName, RunFunctor, &aFunctor, aAutoResume); + } + + ~TTestThread() + { + //RTest::CloseHandleAndWaitForDestruction(iThread); + iThread.Close(); + } + + void Resume() + { + iThread.Resume(); + } + + /** + If thread exited normally, return its return code + Otherwise, leave with exit reason + */ + virtual TInt WaitForExitL() + { + User::WaitForRequest(iLogonStatus); + const TInt exitType = iThread.ExitType(); + const TInt exitReason = iThread.ExitReason(); + + __ASSERT_ALWAYS(exitType != EExitPending, User::Panic(_L("TTestThread"),0)); + + if(exitType != EExitKill) + User::Leave(exitReason); + + return exitReason; + } + + virtual void Rendezvous(TRequestStatus& aStatus) + { + iThread.Rendezvous(aStatus); + } + +private: + void Init(const TDesC& aName, TThreadFunction aFn, TAny* aData, TBool aAutoResume) + { + TKName name(aName); + name.AppendFormat(_L("-%d"), iCount++); + TInt r=iThread.Create(name, aFn, KDefaultStackSize, KPciHeapSize, KPciHeapSize, aData); + if(r!=KErrNone) + { + RDebug::Printf("RThread::Create failed, code=%d", r); + User::Panic(KPciPanicCat, EThreadCreateFailed); + } + + iThread.Logon(iLogonStatus); + __ASSERT_ALWAYS(iLogonStatus == KRequestPending, User::Panic(_L("TTestThread"),0)); + + if(aAutoResume) + iThread.Resume(); + } + + RThread iThread; + }; + +class CTest : public CBase, public TFunctor + { +public: + ~CTest() + { + iName.Close(); + } + + virtual void operator()() + { + RTest test(iName); + test.Start(iName); + for(TInt i=0; i testArray; + RPointerArray threadArray; + + for(TInt i=0; iWaitForExitL()); + if(leaveCode != KErrNone) + { + test.Printf(_L("Thread %d: Panic code:%d\n"), j, leaveCode); + test_KErrNone(leaveCode); + } + + if(r!=KErrNone) + { + test.Printf(_L("Thread Number %d\n"), j); + test_KErrNone(r); + } + } + + threadArray.ResetAndDestroy(); + threadArray.Close(); + + testArray.ResetAndDestroy(); + testArray.Close(); + } +// end of \os\kernelhwsrv\kerneltest\e32test\misc\test_thread.h + +#endif // __KERNEL_MODE__ + +_LIT(KPciLdd, "d_pci.ldd"); +_LIT(KPciLddFactory, "PCI_test_factory"); +_LIT(KPciTest, "PCI Test LDD"); + +/** +Test driver op-codes +*/ +enum TPciTestCmd + { + EGetTestInfo, + EAccessConfigSpace, + EAccessMemorySpace, + EOpenPciDChunk, + EOpenPciPlatHwChunk, + EOpenPciMappedChunk, + EOpenPciWindowChunk, + ERunUnitTests + }; + +/** +Identifies a PCI Function (device) on the system +*/ +struct TPciDevice + { + TPciDevice() + :iVendorId(0xFFFFFFFF), iDeviceId(0xFFFFFFFF), iInstance(0) {} + + TPciDevice(TUint aVendorId, TUint aDeviceId, TInt aInstance=0) + :iVendorId(aVendorId), iDeviceId(aDeviceId), iInstance(aInstance) {} + + TUint iVendorId; + TUint iDeviceId; + TInt iInstance; //< Unit to open (there could be multiple devices on system) + }; + +/** +Used to send chunk size and recieve +PCI address +*/ +struct TPciChunkCreateInfo + { + TPciChunkCreateInfo() + :iSize(0), iPciAddress(NULL) + { + } + + TPciChunkCreateInfo(TInt aSize, TUint& aPciAddress, TRequestStatus* aStatus=NULL) + :iSize(aSize), iPciAddress(&aPciAddress), iStatus(aStatus) + { + } + TInt iSize; + TUint* iPciAddress; + TRequestStatus* iStatus; + }; + +/** +Information about the PSL required by the +user side test +*/ +struct TPciTestInfo + { + TPciDevice iDevice; //< Probe for this + + /** + Supplies the necessary information to test Read, Write, and + Modify for a word of PCI memory or configuration space + */ + struct TAddrSpaceTest + { + TAddrSpaceTest() + :iOffset(0), iExpectedValue(0), iReadOnlyMask(0) + {} + + TAddrSpaceTest(TUint aOffset, TUint aExpectedValue, TUint aReadOnlyMask) + :iOffset(aOffset), iExpectedValue(aExpectedValue), iReadOnlyMask(aReadOnlyMask) + {} + + /** + Returns a specified sub byte, or word from the whole dword + */ + inline TUint Expected(TInt aBitWidth, TInt aExtraOffset) const + { + //the right shift required to get field to bit 0 + const TInt shift = 8 *((aExtraOffset + iOffset) % 4); + + const TUint mask = 0xFFFFFFFF >> (32-aBitWidth); + return (iExpectedValue >> shift) & mask; + } + + const TUint iOffset; + const TUint iExpectedValue; //< The initial value of word + const TUint iReadOnlyMask; //< Mask of unwritable bits + //Future work, memory spaces should state a bar index + }; + + + TAddrSpaceTest iCfgSpaceRead; + TAddrSpaceTest iCfgSpaceWrite; + + TUint iMemSpaceIndex; //< Memory space to select + TAddrSpaceTest iMemSpaceRead; + TAddrSpaceTest iMemSpaceWrite; + + TInt iNumberOfBars; //< Number of simultaneous mappings into PCI space + }; + +class RPci; +class TAddrSpace; +/** +This class encapsulates all the various read/write/and modify commands +that can be carried out on a PCI memory space. The command is stored user +side, and then executed on kernel side when KRun() is called. +*/ +class TUserPciSpace + { +public: + TUserPciSpace() + :iPci(NULL), iOperation(EInvalid), iBitWidth(0), iOffset(0), + iWriteValue(0), iClearMask(0), iSetMask(0) + {} + TUserPciSpace(RPci& aPci); + + /** + Perform the encapsulated read/write/or modify + @note Only run on kernel side + */ + TUint KRun(TAddrSpace& aAddrSpace); + + /** + Clone method is required so that multiple threads may + have their own copy of a TUserPciSpace (without knowing + its runtime type) + */ + virtual TUserPciSpace* Clone() const = 0; + + TUint Read(TInt aBitWidth, TUint aOffset) + { + iOffset = aOffset; + iOperation = ERead; + iBitWidth = aBitWidth; + + return Call(); + } + + void Write(TInt aBitWidth, TUint aOffset, TUint aValue) + { + iOffset = aOffset; + iOperation = EWrite; + iBitWidth = aBitWidth; + + iWriteValue = aValue; + Call(); + } + + void Modify(TInt aBitWidth, TUint aOffset, TUint aClearMask, TUint aSetMask) + { + iOffset = aOffset; + iOperation = EModify; + iBitWidth = aBitWidth; + + iClearMask = aClearMask; + iSetMask = aSetMask; + Call(); + } + +protected: + /** + Makes a request to iPci and passes a copy of this object to + the kernel side. + */ + virtual TUint Call() =0; + + enum TOperation {EInvalid, ERead, EWrite, EModify}; + + /** + Pointer to a PCI device handle + */ + RPci* iPci; + + TOperation iOperation; //!< Type of access to perform + TInt iBitWidth; + + TUint iOffset; + TUint32 iWriteValue; + TUint32 iClearMask; + TUint32 iSetMask; + }; + +/** +Grants access to a PCI device's (identified +by aPci) config space from user side +*/ +class TUserConfigSpace : public TUserPciSpace + { +public: + TUserConfigSpace() + :TUserPciSpace() + {} + TUserConfigSpace(RPci& aPci); + + virtual TUserPciSpace* Clone() const; +private: + TUint Call(); + }; + +/** +Grants access to some region of a PCI +device's memory space. A PCI device(or function) +may have up to 8 distinct memory spaces +*/ +class TUserMemorySpace : public TUserPciSpace + { +public: + TUserMemorySpace() + :TUserPciSpace(), iBarIndex(-1) + {} + + TUserMemorySpace(RPci& aPci, TInt aBarIndex); + + virtual TUserPciSpace* Clone() const; + + inline TInt BarIndex() {return iBarIndex;} + +private: + TUint Call(); + + TInt iBarIndex; //< Each PCI function may have up to 8 memory spaces + }; + +#endif //__TPCI_TEST_H + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/t_csi.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/t_csi.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include + +target VariantTarget(t_csi,exe) +romtarget t_csi.exe +targettype exe + +sourcepath ./csi +source t_csi.cpp + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) +USERINCLUDE ../inc + +library euser.lib hal.lib + +capability all + + +VENDORID 0x70000001 + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/t_gpio.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/t_gpio.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include + +target VariantTarget(t_gpio,exe) +romtarget t_gpio.exe +targettype exe + +sourcepath ./gpio +source t_gpio.cpp + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + +library euser.lib hal.lib + +capability all + +VENDORID 0x70000001 + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/t_pci.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/t_pci.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include + +TARGET VariantTarget(t_pci,exe) +ROMTARGET t_pci.exe +TARGETTYPE EXE +SOURCEPATH ./pci +SOURCE t_pci.cpp +LIBRARY euser.lib +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +CAPABILITY ReadDeviceData WriteDeviceData + +VENDORID 0x70000001 + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/timestamp/d_timestamp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/timestamp/d_timestamp.cpp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,182 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include +#include "d_timestamp.h" +#include "d_timestamp_dev.h" +#include "ne1_tb_power.h" + +// Name for PDD, will be LDD name and this suffix +_LIT(KTimestampPddSuffix,".NE1_TB"); + + +class DNE1_TimestampTestPddChannel : public DTimestampTestPddChannel + { +public: + // Inherited from DTimestampTestPddChanel. These called by the LDD. + virtual void StartLPMEntryCheck(); + virtual TBool EndLPMEntryCheck(); + virtual void TestConfig(STimestampTestConfig& aInfo); +private: + TUint iInitialIdleCount; + }; + +/** + Logical Device (factory class) for DNE1_TimestampTestPddChannel +*/ +class DNE1_TimestampTestPddFactory : public DPhysicalDevice + { +public: + DNE1_TimestampTestPddFactory(); + // Inherited from DLogicalDevice + virtual TInt Install(); + virtual void GetCaps(TDes8& aDes) const; + virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); + virtual TInt Validate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); +private: + TVersion iVersion; + }; + +// +// DNE1_TimestampTestPddFactory +// + +/** + Standard export function for PDDs. This creates a DPhysicalDevice derived object, + in this case, our DNE1_TimestampTestPddFactory +*/ +DECLARE_STANDARD_PDD() + { + return new DNE1_TimestampTestPddFactory(); + } + +/** + * constructor + */ +DNE1_TimestampTestPddFactory::DNE1_TimestampTestPddFactory() + { + // Set version number for this device + iVersion=RTimestampTest::VersionRequired(); + } + +/** + Second stage constructor for DPhysicalDevice derived objects. + This must at least set a name for the driver object. + + @return KErrNone or standard error code. +*/ +TInt DNE1_TimestampTestPddFactory::Install() + { + TName name(RTimestampTest::Name()); + name.Append(KTimestampPddSuffix); + return SetName(&name); + } + +/** + Returns the drivers capabilities. This is not used by the Symbian OS device driver framework + but may be useful for the LDD to use. + + @param aDes Descriptor to write capabilities information into +*/ +void DNE1_TimestampTestPddFactory::GetCaps(TDes8& aDes) const + { + // Create a capabilities object + RTimestampTest::TCaps caps; + caps.iVersion = iVersion; + // Write it back to user memory + Kern::InfoCopy(aDes,(TUint8*)&caps,sizeof(caps)); + } + +/** + Called by the kernel's device driver framework to create a Physical Channel. + This is called in the context of the user thread (client) which requested the creation of a Logical Channel + (E.g. through a call to RBusLogicalChannel::DoCreate) + The thread is in a critical section. + + @param aChannel Set to point to the created Physical Channel + @param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate + @param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate + @param aVer The version number of the Logical Channel which will use this Physical Channel + + @return KErrNone or standard error code. +*/ +TInt DNE1_TimestampTestPddFactory::Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer) + { + // Ignore the parameters we aren't interested in... + (void)aUnit; + (void)aInfo; + (void)aVer; + + // Create a new physical channel + DNE1_TimestampTestPddChannel* channel=new DNE1_TimestampTestPddChannel; + aChannel = channel; + return (channel) ? KErrNone : KErrNoMemory; + } + +/** + Called by the kernel's device driver framework to check if this PDD is suitable for use with a Logical Channel. + This is called in the context of the user thread (client) which requested the creation of a Logical Channel + (E.g. through a call to RBusLogicalChannel::DoCreate) + The thread is in a critical section. + + @param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate + @param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate + @param aVer The version number of the Logical Channel which will use this Physical Channel + + @return KErrNone or standard error code. +*/ +TInt DNE1_TimestampTestPddFactory::Validate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer) + { + // Check version numbers + if (!Kern::QueryVersionSupported(iVersion,aVer)) + return KErrNotSupported; + + (void)aInfo; + (void) aUnit; + return KErrNone; + } + +//// +// Channel implementation + + +/** + Called before each cycle in the test. Takes a copy of current idle count in power controller +*/ +void DNE1_TimestampTestPddChannel::StartLPMEntryCheck() + { + iInitialIdleCount = TNE1_TBPowerController::IdleCount(); + } + +/** + Called at the end of each cycle. Should return true if we have entered idle since call to + StartLPMEntryCheck. This will be the case if the idle count has changed +*/ +TBool DNE1_TimestampTestPddChannel::EndLPMEntryCheck() + { + return (iInitialIdleCount!=TNE1_TBPowerController::IdleCount()); + } + + +/** + Called to allow baseport to override test parameters. For Navi defaults are fine +*/ +void DNE1_TimestampTestPddChannel::TestConfig(STimestampTestConfig& aInfo) + { + } diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/test/variant_test.mmh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/test/variant_test.mmh Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#define NE1_TB +macro __NE1_TB__ +#include <../variant.mmh> diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/variant.mmh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/variant.mmh Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,157 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +// +// TO DO: (mandatory) +// +// Add here a definition for your CPU (list in CONFIG.INC) +// +macro __CPU_ARM11MP__ +// +// TO DO: (mandatory) +// +// Add here a definition for your Memory Model +// +#define MM_MULTIPLE +// +// TO DO: (mandatory) +// +// Macro which generates the names for the binaries for this platform +// +#ifndef VariantTarget +#define VariantTarget(name,ext) _ne1_tb_##name##.##ext +#endif + +#ifndef VariantMediaDefIncludePath +#define VariantMediaDefIncludePath SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(ne1_tb) +#endif + +// Used in MMP files for include paths e.g. to hcrconfig.h header and others +#ifndef VariantIncludePath +#define VariantIncludePath SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) +#endif + +#ifndef AsspIncludePath +#define AsspIncludePath SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +#endif + + +//Include debug support +macro __DEBUGGER_SUPPORT__ + +// +// TO DO: +// +// If euser is built from the variant, uncomment the following line to build it +// as ARM rather than Thumb +// +//#define __BUILD_VARIANT_EUSER_AS_ARM__ +// +// TO DO: (optional) +// +// To replace some of the generic utility functions with variant specific +// versions (eg to replace memcpy with a version optimised for the hardware), +// uncomment the two lines below and edit the files in the replacementUtils +// directory. +// +//#define REPLACE_GENERIC_UTILS +//#define VariantReplacementUtilsPath ne1_tb/replacement_utils +// +// TO DO: (optional) +// +// Enable BTrace support in release versions of the kernel by adding +// the following BTRACE macro declarations +// +macro BTRACE_KERNEL_ALL +// +// TO DO: +// +// Uncomment the following line if using the r1p0 release or later of the ARM1136 processor. +// +//#define __CPU_ARM1136_IS_R1__ +// + +// Include the following line if default memory mapping should use shared memory. +// Should be on for multicore (SMP) devices. + +macro __CPU_USE_SHARED_MEMORY + +// Include the following line if CPU cannot tolerate the presence of nonshared +// cached memory. This seems to be the case for the ARM11 MPCore - corruption +// of data is observed in non-shared cached regions if __CPU_USE_SHARED_MEMORY +// is used. + +macro __CPU_FORCE_SHARED_MEMORY_IF_CACHED + + + +// TO DO: +// +// Uncomment the next line if using the ARM1136 processor and ARM1136 Erratum 406973 +// "CLREX instruction might be ignored during data cache line fill" +// is fixed on this hardware. +// +//#define __CPU_ARM1136_ERRATUM_406973_FIXED + +// Uncomment next line if using the ARM1136 processor and ARM1136 Erratum 408022 +// "Cancelled write to CONTEXTID register might update ASID" +// is fixed on this hardware. +// +//#define __CPU_ARM1136_ERRATUM_408022_FIXED + + +// Uncomment if: +// 1) using ARM1136 processor and ARM1136 Erratum 411920: "Invalidate Entire Instruction Cache +// operation might fail to invalidate some lines if coincident with linefill" +// is fixed on this hardware, or +// 2) using ARM1176 processor and ARM1176 Erratum 415045: "Invalidate Entire Instruction Cache +// operation might fail to invalidate some lines if coincident with linefill +// is fixed on this hardware. +// Workaround: +// 1) Disables the use of of prefetch range cache operations by setting RV bit in Auxiliary Ctrl Reg. +// 2) Replaces Invalidate ICache operation with the sequence defined in the errata document. +// If this macro is enabled, it should be accompanied by: +// "GBLL CFG_CPU_ARM1136_ERRATUM_411920_FIXED" in variant.mmh +// +// #define __CPU_ARM1136_ERRATUM_411920_FIXED + +macro FAULTY_NONSHARED_DEVICE_MEMORY + +// SMP Timestamp uses inline code from BSP +macro __NKERN_TIMESTAMP_USE_INLINE_BSP_CODE__ +#define AsspNKernIncludePath SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(assp/naviengine/nkern) + +// FIQ can not be disabled on naviengine, tell kernel to ignore it... +macro __FIQ_IS_UNCONTROLLED__ + +macro MONITOR_THREAD_CPU_TIME + +#if defined(__USING_USING_ASSP_REGISTER_API__) || defined(__USING_INTERRUPT_API__) || defined(__USING_ASSP_REGISTER_API__) +library VariantTarget(kanaviengine,lib) +#endif + +// Include CrazyInterrupts support (changing CPU targets for following HW interrupts) +// comment this macro - once SMP kernel is fully functional +macro SMP_CRAZY_INTERRUPTS + +// Include VFP support +macro __CPU_HAS_VFP +#define USE_VFP_MATH + +// Include GPIO STATIC EXTENSION +macro __USE_GPIO_STATIC_EXTENSION__ + diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/variant.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/variant.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/variant.mmp +* ecust.dll ne1_tb variant library +* +*/ + + + +/** + @file +*/ +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(ecust,dll) +targettype var2 +linkas ecust.dll + +USERINCLUDE inc +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) +USERINCLUDE specific +#ifdef SMP +USERINCLUDE ../../../../os/kernelhwsrv/kernel/eka/include/drivers/smppower/sample_idlehandler +#endif + + +sourcepath specific +source variant.cpp +source variant.cia + +library VariantTarget(power,lib) + +deffile ./~/variant.def +nostrictdef + +epocallowdlldata + +uid 0x1000008d 0x100039e8 + +VENDORID 0x70000001 + +capability all + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/watchdog.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/watchdog.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/exlcdne1_tb.mmp +* lcd.dll NE1_TBVariant LCD driver +* +*/ + + + +/** + @file +*/ +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "kernel/kern_ext.mmh" + +target VariantTarget(watchdog,dll) +targettype kext +romtarget watchdog.dll + +//systeminclude /epoc32/include/drivers +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) + +//systeminclude /epoc32/include/ne1_tb +//systeminclude /epoc32/include/ne1_tb/specific + +sourcepath ../naviengine_assp +source watchdog.cpp + +library VariantTarget(ecust,lib) +library resman.lib + +noexportlibrary +deffile ../../../../os/kernelhwsrv/kernel/eka/~/empty.def + +epocallowdlldata + +uid 0x1000008d 0x100039e8 + +VENDORID 0x70000001 + +capability all + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/ne1_tb/xyin.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/ne1_tb/xyin.mmp Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* ne1_tb/xyin.mmp +* exyin.dll NE1_TBVariant digitizer library +* +*/ + + + +/** + @file +*/ +#define __USING_ASSP_REGISTER_API__ +#define __USING_ASSP_INTERRUPT_API__ + +#include +#include "kernel/kern_ext.mmh" + +// uncomment the following line if you don't want to use LCD panel in polling mode +// #define _USE_INTERRUPTS_ + +#ifdef _USE_INTERRUPTS_ +macro USE_PEN_INTERRUPTS +library VariantTarget(gpio,lib) +#endif + + +target VariantTarget(exyin,dll) +targettype kext +linkas exyin.dll + +SYMBIAN_BASE_SYSTEMINCLUDE(drivers) + +SYMBIAN_ASSP_SYSTEMINCLUDE(naviengine) +SYMBIAN_BASE_SYSTEMINCLUDE(ne1_tb) +SYMBIAN_NE1_TB_SYSTEMINCLUDE(specific) +USERINCLUDE inc +USERINCLUDE ../naviengine_assp/lcdgce + +sourcepath ../../../../os/kernelhwsrv/kernel/eka/drivers/xyin +source d_xyin.cpp + +sourcepath specific +source xyin.cpp + +library VariantTarget(ecust,lib) + +noexportlibrary +deffile ../../../../os/kernelhwsrv/kernel/eka/~/empty.def + +uid 0x1000008d 0x100039ea + +VENDORID 0x70000001 + +capability all + +//CPU_AFFINITY_ANY + +SMPSAFE diff -r 000000000000 -r 5de814552237 navienginebsp/tools/bootloader/flashldr.bin Binary file navienginebsp/tools/bootloader/flashldr.bin has changed diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/Platforms/ne1_tb/attach.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/Platforms/ne1_tb/attach.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,69 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// Attaches to a running NaviEngine and stops the currently running CPU core. +// +// Change History: +// +// 11/11/2008 1.0 : Initial version +// 08/05/2009 1.1 : Tidied up in readiness for putting into Nokia's distribution system +// +////////////////////////////////////////////////////////////////////////////// + +&scriptversion=1.1 + +print "=======================================================================" +print "&Platform attach script version &scriptversion" + +; Detach from the board +sys.down + +; Reset the jtag unit +system.reset +system.cpu &CpuType + +; ETM is not supported so ensure that it is off +etm.off +etm.datatrace off + +if ("&SystemOptionEnreset"!="") + ( + system.option enreset &SystemOptionEnreset + ) + +; VFP uses undefined instructions to operate, so switch off the UNDEF exception to +; prevent us getting millions of false halts +if ("&OnChipTriggerUndef"!="") + ( + tronchip.set undef &OnChipTriggerUndef + ) + +if ("&JtagClock"!="") + ( + system.jtagclock &JtagClock + ) + +; Attach to the current CPU core and stop it +sys.mode.attach + +if run() + ( + print "Stopping the running CPU core..." + break + ) + +enddo diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/Platforms/ne1_tb/defaultsourcepaths.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/Platforms/ne1_tb/defaultsourcepaths.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,53 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +//////////////////////////////////////////////////////////////////////////////// +// +// SOURCE PATHS +// +// Source paths is a very complicated topic. For a better tutorial about them, +// visit the Trace32 wiki: +// +// http://wikis.in.nokia.com/BoardSupportPackagesSymbian/T32 +// +// The basics of source paths are: +// +// - they are used in the order they are defined +// - if a source file is found by following a path, it will be ignored if it +// exists in another path. ie. the first one found sticks. +// - The classic example is main.cpp as it exists in many test executeables. +// - This is a problem when you are debugging and the file you want is not the +// first on the list. +// - you resolve this by ordering the source paths correctly so that the file +// you are interested in gets found first. +// +// Other underlying commands that are used by the scripts, so hopefully you +// don't have to: +// +// - SYMBOL.SPATH.RESET will clear out the current source path list +// - STORE SPATH will save the source paths to a file +// - DO will reload the source paths from a file +// +//////////////////////////////////////////////////////////////////////////////// +; extract the drive letter and add it to the symbol path +//&driveletter=string.mid(os.file.path(&_SYMBOLICS_FILENAME),0.,2.) + +SYMBOL.SPATH.RESET +SYMBOL.SPATH.SETRECURSEDIR "&driveletter&sospath\os\boardsupport\naviengine" +SYMBOL.SPATH.SETRECURSEDIR "&driveletter&sospath\os\kernelhwsrv\kernel\eka\drivers" +SYMBOL.SPATH.SETRECURSEDIR "&driveletter&sospath\os\kernelhwsrv\kernel\eka\nkernsmp" +SYMBOL.SPATH.SETRECURSEDIR "&driveletter&sospath\os\kernelhwsrv\kernel\eka\kernel" +SYMBOL.SPATH.SET "&driveletter\epoc32\release\armv5smp\UDEB" + diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/Platforms/ne1_tb/flash.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/Platforms/ne1_tb/flash.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,109 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// NaviEngine NOR flash download script +// +// Change History: +// +// 11/11/2008 1.0 : Initial version +// 12/02/2009 1.1 : Merged working script in from old naviengine_flash.cmm +// 08/05/2009 1.2 : Updated to accept the image name and address passed as parameters +// +////////////////////////////////////////////////////////////////////////////// + +&scriptversion=1.2 +entry &imageName &imageAddr &skipHeader + +print "=======================================================================" +print "&Platform NOR flashing script &scriptversion" + +; Stop all CPU cores on the board to prevent them interfering with the flashing +do &PlatformsDir\&Platform\stopcpus.cmm + +; Reset the Lauterbach flash configuration +flash.reset + +; Configure the flash to either use a helper executable on the machine (faster) or +; to use the Lauterbach (slower) to perform the writing +if "&FlashOptionTarget"=="yes" + ( + ; Target controlled flashing requires a binary downloaded to the development board + print "Using target assisted flashing" + flash.create 1. &FlashStart--&FlashEnd &FlashBlockSize TARGET &FlashWidth + + ; Determine where to store the target binary (and how big it is) + flash.target &RamAddr &RamAddr+0x1000 0x1000 ../demo/arm/flash/&FlashWidth/&FlashType.bin + ) + else + ( + ; Emulator controlled flashing is controlled from the host and is a lot slower + print "Using basic emulator flashing (slow)" + flash.create 1. &FlashStart--&FlashEnd &FlashBlockSize &FlashType &FlashWidth + ) + +; Determine the size of the image to be written +&fileSize=os.file.size(&imageName) + +print "Flash Configuration:" +print "-----------------------------" +print "RAM address: &RamAddr" +print "Image name: &imageName" +print "Image Size: &fileSize" +print "Image Skip Header: &skipHeader" +print "Flash Start: &imageAddr" +print "Flash End: &FlashEnd" +print "Flash Type: &FlashType" +print "Flash Block Size: &FlashBlockSize" +print "Flash Width: &FlashWidth" +print "-----------------------------" + +flash.unlock &imageAddr++&fileSize +flash.erase &imageAddr++&fileSize +flash.program &imageAddr++&fileSize + +if "&skipHeader"=="true" + ( + print "Skipping EPOC header" + data.load.binary "&imageName" &imageAddr /SKIP 100 + ) +else + ( + data.load.binary &imageName &imageAddr /WORD + ) + +; Programming done, relock the flash +flash.program off +flash.lock 1. + +; Compare what we wrote against what is there now +print "Verifying image..." +if "&skipHeader"=="true" + ( + data.load.binary "&imageName" &imageAddr /SKIP 100 /compare + ) +else + ( + data.load.binary "&imageName" &imageAddr /compare + ) + +; On an error the script will abort before printing OK (and print the error) +print "Verified OK. Flash programming completed" + +; Disconnect the JTAG as the user is likely to power cycle the board and it might confuse us +sys.down + +enddo diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/Platforms/ne1_tb/flasherase.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/Platforms/ne1_tb/flasherase.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,79 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// NaviEngine NOR flash erasing script. +// +// Change History: +// +// 11/11/2008 1.0 : Initial version +// 08/05/2009 1.1 : Tidied up in readiness for putting into Nokia's distribution system +// +////////////////////////////////////////////////////////////////////////////// + +&scriptversion=1.1 + +print "=======================================================================" +print "&Platform NOR flash erasing script &scriptversion" + +; Stop all CPU cores on the board to prevent them interfering with the flashing +do &PlatformsDir\&Platform\stopcpus.cmm + +; Reset the Lauterbach flash configuration +flash.reset + +; Configure the flash to either use a helper executable on the machine (faster) or +; to use the Lauterbach (slower) to perform the writing +if "&FlashOptionTarget"=="yes" + ( + ; Target controlled flashing requires a binary downloaded to the development board + print "Using target assisted flashing" + flash.create 1. &FlashStart--&FlashEnd &FlashBlockSize TARGET Word + + ; Determine where to store the target binary (and how big it is) + flash.target &RamAddr &RamAddr+0x1000 0x1000 ../demo/arm/flash/&FlashWidth/&FlashType.bin + ) + else + ( + ; Emulator controlled flashing is controlled from the host and is a lot slower + print "Using basic emulator flashing (slow)" + flash.create 1. &FlashStart--&FlashEnd &FlashBlockSize &FlashType &FlashWidth + ) + +print "Flash Configuration:" +print "---------------------------------" +print "Flash Start: &FlashStart" +print "Flash Length: &FlashLength" +print "Flash End: &FlashEnd" +print "Flash Type: &FlashType" +print "Flash Block Size: &FlashBlockSize" +print "Flash Width: &FlashWidth" +print "---------------------------------" + +flash.unlock &FlashStart++&FlashLength +flash.erase &FlashStart++&FlashLength + +; Programming done, relock the flash +flash.program off +flash.lock 1. + +; On an error the script will abort before printing OK (and print the error) +print "Flash programming completed OK" + +; Disconnect the JTAG as the user is likely to power cycle the board and it might confuse us +sys.down + +enddo diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/Platforms/ne1_tb/init.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/Platforms/ne1_tb/init.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,136 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// This script will perform a full hardware initialisation of the NaviEngine board. +// +// Change History: +// +// 01/01/2008 1.0 : Initial version +// 08/05/2009 1.1 : Tidied up in readiness for putting into Nokia's distribution system +// +////////////////////////////////////////////////////////////////////////////// + +&scriptversion=1.1 + +print "=======================================================================" +print "&Platform initialisation script version &scriptversion" + +; Initialise system control coprocessor +print "Initialising system control coprocessor" + +; p15, , Rd, CRn, CRm, +; BIT0-3:CRn +; BIT4-7:CRm +; BIT8-10: +; BIT12-14: + +;*CPU Init +;*MMU/D-cache/I-cache disabled +; c1, 0, c0, 0 +core 0 +d.s C15:0x0001 %LE %LONG 0x00054078 +core 1 +d.s C15:0x0001 %LE %LONG 0x00054078 +core 2 +d.s C15:0x0001 %LE %LONG 0x00054078 +core 3 +d.s C15:0x0001 %LE %LONG 0x00054078 + +;*Invalidate both caches +; c7, 0, c7, 0 +d.s C15:0x0077 %LE %LONG 0x0 + +;*Invalidate TLBs +; c8, 0, c7, 0 +d.s C15:0x0078 %LE %LONG 0x0 + +system.resettarget +print "Initialising bus controller and peripherals" + +;*DDR2 Init +data.set sd:0x18021044 %LE %LONG 0x30022123 +data.set sd:0x18021058 %LE %LONG 0x00000001 +data.set sd:0x18021008 %LE %LONG 0x00000020 + +wait.1s + +;*delay(Memo Register dummy write) +data.set sd:0x18037C0C %LE %LONG 0x00000000 +data.set sd:0x18021008 %LE %LONG 0x10000004 +data.set sd:0x18021008 %LE %LONG 0x00010002 +data.set sd:0x18021008 %LE %LONG 0x00018002 +data.set sd:0x18021008 %LE %LONG 0x00008002 +data.set sd:0x18021008 %LE %LONG 0X1D480002 +data.set sd:0x18021008 %LE %LONG 0x10000004 +data.set sd:0x18021008 %LE %LONG 0x00000001 +data.set sd:0x18021008 %LE %LONG 0x00000001 + +;*delay(Memo Register dummy write) +data.set sd:0x18037C0C %LE %LONG 0x00000000 +data.set sd:0x18037C0C %LE %LONG 0x00000000 +data.set sd:0x18037C0C %LE %LONG 0x00000000 +data.set sd:0x18021008 %LE %LONG 0x19480002 +data.set sd:0x18021008 %LE %LONG 0x01308002 +data.set sd:0x18021008 %LE %LONG 0x00000100 +data.set sd:0x18021040 %LE %LONG 0x1485A912 +data.set sd:0x18021034 %LE %LONG 0x00000121 + +;*SysCon Init +;* .word 0x18037C80 %LE %LONG 0x007F0103 +data.set sd:0x18037C80 %LE %LONG 0x00000000 + +;*ExBus Init +data.set sd:0x1801A000 %LE %LONG 0x0000004A +data.set sd:0x1801A004 %LE %LONG 0x08000049 +data.set sd:0x1801A008 %LE %LONG 0x0600004E +data.set sd:0x1801A00C %LE %LONG 0x0400004B +data.set sd:0x1801A010 %LE %LONG 0x1000004A +data.set sd:0x1801A014 %LE %LONG 0x1400000A +data.set sd:0x1801A020 %LE %LONG 0x10388E7F +data.set sd:0x1801A024 %LE %LONG 0x10388E7E +data.set sd:0x1801A028 %LE %LONG 0x10388E7E +data.set sd:0x1801A02C %LE %LONG 0x10388E7F +data.set sd:0x1801A030 %LE %LONG 0x10388E7E +data.set sd:0x1801A034 %LE %LONG 0x10388E7E + +;*ExBus PCS5 UART-EX Init +d.s SD:0x14020003 %LE %BYTE 0x00 +d.s SD:0x14020001 %LE %BYTE 0x00 +d.s SD:0x14020002 %LE %BYTE 0x07 +d.s SD:0x14020003 %LE %BYTE 0x80 +d.s SD:0x14020000 %LE %BYTE 0x1E +d.s SD:0x14020001 %LE %BYTE 0x00 +d.s SD:0x14020003 %LE %BYTE 0x03 +d.s SD:0x14020004 %LE %BYTE 0x03 + +;*ExBus PCS5 CharLED +d.s SD:0x14000000 %LE %BYTE 0x59 +d.s SD:0x14000001 %LE %BYTE 0x45 +d.s SD:0x14000002 %LE %BYTE 0x53 +d.s SD:0x14000003 %LE %BYTE 0x21 +d.s SD:0x14000004 %LE %BYTE 0x21 +d.s SD:0x14000005 %LE %BYTE 0x20 +d.s SD:0x14000006 %LE %BYTE 0x20 +d.s SD:0x14000007 %LE %BYTE 0x20 + +;*ExBus PCS4 LED +d.s SD:0x10000030 %LE %WORD 0x00AA + +data.set sd:0x18037C14 %LE %LONG 0x00000000 + +enddo + diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/Platforms/ne1_tb/platformconfig.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/Platforms/ne1_tb/platformconfig.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,48 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +&CpuType="arm11mpcoresmp4" +&JtagClock="rtck" + +&NumberOfCpus="4" + +&OnChipTriggerFiq="" +&OnChipTriggerIrq="" +&OnChipTriggerDabort="" +&OnChipTriggerPabort="" +&OnChipTriggerSwi="" +&OnChipTriggerUndef="off" +&OnChipTriggerReset="" +&OnChipTriggerAlignment="" +&OnChipTriggerStepvector="" +&OnChipTriggerAddress="" +&OnChipTriggerError="" + +&SystemOptionEnreset="off" +&SystemOptionTurbo="off" +&SystemOptionDismode="" +&SystemOptionNoircheck="" +&SystemOptionWaitreset="" +&SystemOptionResbreak="" +&SystemOptionDacr="" +&SystemOptionTidbgen="" + +&FlashType="AM29LV256" +&FlashBlockSize=0x20000 +&FlashStart=0x00000000 +&FlashLength=0x3FFFFFF +&FlashEnd=&FlashStart+&FlashLength +&FlashWidth="word" +&FlashOptionTarget="yes" diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/Platforms/ne1_tb/stopcpus.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/Platforms/ne1_tb/stopcpus.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,84 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// NaviEngine script to stop all CPU cores. +// +// Change History: +// +// 08/05/2009 1.0 : Initial version +// +////////////////////////////////////////////////////////////////////////////// + +// Why is this required? +// Because it doesn't work if we use cpu type as &CpuType! +// Someone should work out why.... +sys.cpu ARM11MPCORE + +; CPU 3 +print "Stopping core 3..." +system.multicore irpre 0. +system.multicore drpre 0. +system.multicore irpost 15. +system.multicore drpost 3. + +sys.mode.attach + +if run() + break; + +sys.down + +; CPU 2 +print "Stopping core 2..." +system.multicore irpre 5. +system.multicore drpre 1. +system.multicore irpost 10. +system.multicore drpost 2. + +sys.mode.attach + +if run() + break; + +sys.down + +; CPU 1 +print "Stopping core 1..." +system.multicore irpre 10. +system.multicore drpre 2. +system.multicore irpost 5. +system.multicore drpost 1. + +sys.mode.attach + +if run() + break; + +sys.down + +; CPU 0 +print "Stopping core 0..." +system.multicore irpre 15. +system.multicore drpre 3. +system.multicore irpost 0. +system.multicore drpost 0. + +sys.mode.attach + +if run() + break; + diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/Platforms/ne1_tb/userconfig.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/Platforms/ne1_tb/userconfig.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,32 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +&Platform="ne1_tb" +&AutoloadModule="" +&RamAddr="0x80000000" +&RamImage="X:\sf\os\kernelhwsrv\kernel\eka\rombuild\FNE1_TBARMV5SMP-TSHELL-D.IMG" +&RamAddr1="0x80000000" +&RamImage1="X:\sf\os\kernelhwsrv\kernel\eka\rombuild\SNE1_TBARMV5-TSHELL-D.IMG" +&RamAddr2="0x80000000" +&RamImage2="X:\sf\os\kernelhwsrv\kernel\eka\rombuild\NE1_TBARMV5-TSHELL-D.IMG" +&RamAddr3="0x80000000" +&RamImage3="X:\sf\os\kernelhwsrv\kernel\eka\rombuild\FNE1_TBARMV5-TSHELL-D.IMG" +&RamAddr4="0x80000000" +&RamImage4="X:\sf\os\kernelhwsrv\kernel\eka\rombuild\FNE1_TBARMV5SMP-TSHELL-D.IMG" +&FlashAddr="0" +&FlashImage="X:\sf\os\kernelhwsrv\kernel\eka\rombuild\NE1_TBARMV5D-BOOTLDR-FAT32-D.IMG" +&FlashWriteProtect="ON" +&FlashEraseProtect="ON" diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/attach.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/attach.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,54 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// This script will attach to the board for debugging. It is designed to be +// used in conjunction with the board configuration system to be found in +// configdialog.cmm. +// +// Change History: +// +// 11/11/2008 1.0 : Initial version +// 06/02/2009 1.1 : Tidied up in readiness for putting into Nokia's distribution system +// +////////////////////////////////////////////////////////////////////////////// + +&scriptversion=1.1 + +print "=======================================================================" +print "Generic attach script version &scriptversion" + +; Declare the global variables used by the system and read the current config into them +do globals.cmm + +; Reset t32 symbolics +system.reset + +; Turn on spotlight everywhere +setup.var.%SPOTLIGHT.on + +; Now do the platform specific operations +if os.file("&PlatformsDir\&Platform\attach.cmm") + ( + do &PlatformsDir\&Platform\attach.cmm + ) +else + ( + print "No platform specific attach script available, trying generic attaching" + sys.mode.attach + ) + +print "Trace32 is now attached to the board" diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/autoload.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/autoload.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,98 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// Autoload script, called by TRACE32 if symbols are to be loaded. +// +// Change History: +// +// 03/08/2004 0.1 : Initial symbian version +// 06/08/2004 2.0 : Rolled version to 2.0 for release +// 04/05/2005 4.0 : Rolled version to 4.0 for release +// 12/05/2009 4.1 : Tidied up in readiness for putting into Nokia's distribution system +// 12/08/2009 4.2 : Added support for loading SBSv2 generated symbol files +// 14/10/2009 4.3 : When manually loading .sym files, file dialog now displays sensible wildcards +////////////////////////////////////////////////////////////////////////////// + +&scriptversion=4.3 + +; define local macros +local &_FILENAME &basename &progname &filepath &code &data &space &databsslinear &symfilename &wildcard + +; get _FILENAME and relocation information +; these parameters are passed when calling this skript +entry &_FILENAME &code &data &databsslinear &space + +; &_FILENAME: name of process/file +; &code: text segment address +; &data: data segment address (not used in Symbian OS) +; &databsslinear: combined data & bss segment address +; &space: space id of process (not used here) + +;area.select ramdl +print "Symbolics request: &_FILENAME &code &data &databsslinear &space" +; get symbol file name and program name +&basename=string.cut(&_FILENAME,-string.len(os.file.extension(&_FILENAME))) +&progname=os.file.name("&basename") + +; delete program if it already exists or other code is already there + y.delete &code + if y.exist("\\&progname") + y.delete \\&progname + +; Determine whether to use SBSv1 or SBSv2 symbol file +do checksymbols.cmm &_FILENAME + +; We've decided which symbol file to use so go ahead and try to load it +if !os.file("&filepath") + ( + local &file + &file=os.file.path(&_FILENAME) + winpos ,,,,,, filebox normal "Searching symbols for &_FILENAME" + &wildcard="&file"+"\*.sym" + dialog.file "&wildcard" + entry %line &filepath + &symfilename="&filepath" + if "&filepath"=="" + enddo + ) + +; load symbol file (options for sourcepath, e.g. /STRIPPART may need to be added when required) +if string.scan(string.lwr("&_FILENAME"),"arm4",0)!=-1 + ( + print "Symbolics found ARM4: &symfilename" + data.load.exe "&filepath" /noclear /cpp /nocode /strippart 3 /reloc .text at &code /reloc .data at &databsslinear /reloc .bss after .data + ) +else if string.scan(string.lwr("&_FILENAME"),"armv5",0)!=-1 + ( + print "Symbolics found ARMV5: &symfilename" + ; Idea from baseporting database 2/8/2004 + ; data.load.elf .. /reloc ER_RO at XXXX + ; data.load.elf "&filepath" &newcode /noclear /cpp /nocode /dwarf /rvct /strippart 3 +; autoload5.cmm: d.load.elf "&filepath" /noclear /cpp /nocode /rvct /dwarf /reloc ER_RO at &code + ; BSS/global pointers aren't being setup properly + ; My best attempt + ;data.load.elf "&filepath" /noclear /cpp /nocode /rvct /dwarf /strippart 3 /reloc ER_RO at &code /reloc .data at &databsslinear /reloc .bss after .data + ; From Rudi (04/03/05) + data.load.elf "&filepath" /noclear /cpp /nocode /strippart 3 /reloc ER_RO at &code /reloc ER_RW at &databsslinear /reloc ER_ZI after ER_RW + ) +else + ( + print "Symbolics defaulting to ARMV5: &symfilename" + data.load.elf "&filepath" /noclear /cpp /nocode /rvct /dwarf /strippart 3 /reloc ER_RO at &code /reloc .data at &databsslinear /reloc .bss after .data + ) + +enddo diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/checksymbols.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/checksymbols.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,83 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// A script to check what symbol files are available that match a particular +// component, such as filename.dll. This is used to determine whether to use +// SBSv1 (filename.sym) or SBSv2 (filename.dll.sym) symbol files. +// +// Parameters: +// +// filename: The fully qualified name of the file for which to find the symbols. +// Due to a quirk in the operation of the autoload.cmm script that +// calls this (among others), this must be enclosed in " characters +// +// Change History: +// +// 12/08/2008 1.0 : Initial version +////////////////////////////////////////////////////////////////////////////// + +&scriptversion=1.0 + +entry &filename +local &sbsv1symfilename &sbsv2symfilename + +; Have a look for SBSv1 symbol files (somefile.sym) and SBSv2 symbol files (somefile.dll.sym) and use +; whichever are found. To avoid confusion and using the wrong symbol files we won't allow the situation +; where the user has been mixing SBSv1 and SBSv2 builds. If both sets of symbols are found for a +; particular component then we will stop processing +&sbsv1symfilename="" +&sbsv2symfilename="" + +; Any SBSv1 symbol file present (somefile.sym)? +&basename=string.cut(&filename,-string.len(os.file.extension(&filename))) +&symfilename="&basename"+".sym" +&filepath=y.searchfile("&symfilename") +if os.file("&filepath") + ( + &sbsv1symfilename="&symfilename" + ) + +; Any SBSv2 symbol file present (somefile.dll.sym)? +&symfilename=string.cut(&filename,0)+".sym" +&filepath=y.searchfile("&symfilename") +if os.file("&filepath") + ( + &sbsv2symfilename="&symfilename" + ) + +; If both SBSv1 and SBSv2 symbol files are present then we could check to see which are the newest and use those, +; but we'll refuse to continue as this is safer +if ("&sbsv1symfilename"!="")&&("&sbsv2symfilename"!="") + ( + print "*** Symbol loading aborted (Both SBSv1 and SBSv2 symbolics were detected - please do not mix these) ***" + print "*** Best solution is to clean your component, manually ensure all related symbol files are deleted ***" + print "*** from the UDEB directory (ie. component_name*.sym) and rebuild your component. ***" + + stop + ) +else if ("&sbsv1symfilename"!="") + ( + &symfilename="&sbsv1symfilename" + ) +else + ( + &symfilename="&sbsv2symfilename" + ) + +&filepath=y.searchfile("&symfilename") + +enddo diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/configdialog.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/configdialog.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,846 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// This script will display a dialog box to the user that is the central point +// for configuring the path of the ROM image that is to be loaded onto the +// different boards supported by the Symbian T32 scripts. It is also used to +// select the current target board. Once this has been done, all operations +// such as attaching, loading etc. will be performed on that board, according +// to the settings saved by this script. +// +////////////////////////////////////////////////////////////////////////////// + +// +// 1) load current environment into temporary variables +// if environment not set, take defaults +// 2) initialise dialog with current environment +// ... dialog runs at this point ... +// 3) when dialog exits, update current environment +// + +; Declare the global variables used by the system and read the current config into them +do globals.cmm + +GLOBAL &platformList +GLOBAL &ConfigDialogOpen +&ConfigDialogOpen="false" + +// I'm saving this as a global for now so that I can change the default extension for testing... +GLOBAL &defaultExt +&defaultExt="*.bin;*.img" + +¤tConfigFile="currentconfig.cmm" + +global &dialogMode + +gosub LoadPlatformFromFile "currentconfig.cmm" + +// Stop command prevents script from exiting before user has pressed anything... +stop + +enddo + +//============================================================================= +// Dialog Box Definition +//============================================================================= +OpenDialog: + + gosub GeneratePlatformList + //print "Setting platform list to " "&platformList" + do sourcepaths.cmm + + dialog +(& + header "Current Configuration" + +//*****************************Definition*************************************** + + //---------- Platform ---------- + pos 1. 0. 9. + text "Target Board" + pos 1. 1. 25. 1. +PLATFORM: PULLDOWN "&platformList" "gosub LoadPlatformFromFile" + + //---------- Platform Defaults Box ---------- + pos 27. 0. 17. 3. + box "Target Board Defaults" + + //---------- Defaults Button ---------- + pos 28. 1. 7. 1. + BUTTON "Reload" + ( + gosub LoadPlatformFromFile + ) + + //---------- Save As Defaults Button ---------- + pos 36. 1. 7. 1. + BUTTON "Save" + ( + gosub SavePlatform + ) + + + //---------- Custom Config Box ---------- + pos 45. 0. 19. 3. + box "Custom Config" + + //---------- Load Button ---------- + pos 46. 1. 8. 1. + BUTTON "Load..." + ( + dialog.file "*.cmm" + entry &fileName + + if "&fileName"!="" + ( + gosub LoadPlatformFromFile &fileName + ) + ) + + //---------- Save Button ---------- + pos 55. 1. 8. 1. + BUTTON "Save As..." + ( + dialog.filew "*.cmm" + entry &fileName + if ("&fileName"!="") + ( + gosub SavePlatformToFile &fileName + ) + ) + + //---------- Source Paths and Autoload Module ---------- + pos 0. 2. 75. 4. + box "Source Paths and Autoload Module" + + //---------- Source Paths ---------- + pos 1. 3. 12. 1. + text "Source Paths" + pos 20. 3. 7. 1. +LIST_SOURCEPATHS: BUTTON "List" "gosub ListSourcePaths" + pos 28. 3. 7. +EDIT_SOURCEPATHS: BUTTON "Edit" "gosub EditSourcePath" + pos 36. 3. 7. 1. +RELOAD_SOURCEPATHS: BUTTON "Reload" "gosub ReloadSourcePaths" + pos 44. 3. 7 +DEFAULT_SOURCEPATHS: BUTTON "Default" "gosub DefaultSourcePaths" + pos 52. 3. 7 +SAVE_SOURCEPATHS: BUTTON "Save" "gosub SaveSourcePaths" + + //---------- Autoload Module ---------- + pos 1. 4. 15. + text "Autoload Module" + pos 20. 4. 54. 1. +AUTOLOAD_MODULE: EDIT "" "" + + //-------- RAM Image ------- + pos 0. 6. 90. 10. + box "RAM Images" + pos 1. 7. 15. 1. + text "Load Address 1" + pos 20. 7. 20. 1. +RAMADDR1: EDIT "" "" + pos 1. 8. 15. 1. + text "Filename 1" + pos 20. 8. 65. 1. +RAMIMAGE1: EDIT "" "" + pos 86. 8. 3. + BUTTON "..." + ( + gosub GetImageFromUser RAMIMAGE1 + ) + + pos 1. 9. 15. 1. + text "Load Address 2" + pos 20. 9. 20. 1. +RAMADDR2: EDIT "" "" + pos 1. 10. 15. 1. + text "Filename 2" + pos 20. 10. 65. 1. +RAMIMAGE2: EDIT "" "" + pos 86. 10. 3. + BUTTON "..." + ( + gosub GetImageFromUser RAMIMAGE2 + ) + + pos 1. 11. 15. 1. + text "Load Address 3" + pos 20. 11. 20. 1. +RAMADDR3: EDIT "" "" + pos 1. 12. 15. 1. + text "Filename 3" + pos 20. 12. 65. 1. +RAMIMAGE3: EDIT "" "" + pos 86. 12. 3. + BUTTON "..." + ( + gosub GetImageFromUser RAMIMAGE3 + ) + + pos 1. 13. 15. 1. + text "Load Address 4" + pos 20. 13. 20. 1. +RAMADDR4: EDIT "" "" + pos 1. 14. 15. 1. + text "Filename 4" + pos 20. 14. 65. 1. +RAMIMAGE4: EDIT "" "" + pos 86. 14. 3. + BUTTON "..." + ( + gosub GetImageFromUser RAMIMAGE4 + ) + + //-------- NOR Flash Image ------- + pos 0. 15. 90. 5. + box "NOR Flash Image" + pos 1. 16. 15. 1. + text "Load Address" + pos 20. 16. 20. 1. +FLASHADDR: EDIT "" "" + pos 1. 17. 15. 1. + text "Filename" + pos 20. 17. 65. 1. +FLASHIMAGE: EDIT "" "" + pos 86. 17. 3. +GETFLASHIMAGE: BUTTON "..." + ( + gosub GetImageFromUser FLASHIMAGE + ) + pos 1. 18. 19. 1. + text "Warning Dialogs" + pos 20. 18. 10. 1. +FLASHWRITEPROTECT: CHECKBOX "Flash Write" + ( + print "Write Prot: &FlashWriteProtect" + ) + pos 35. 18. 10. 1. +FLASHERASEPROTECT: CHECKBOX "Flash Erase" + ( + print "Erase Prot: &FlashEraseProtect" + ) + + + //---------- Bottom Row of Buttons ---------- + //---------- OK Button ---------- + pos 1. 20. 6. + DEFBUTTON "OK" + ( + gosub CloseDialog save + continue + ) + + //---------- Cancel Button ---------- + pos 8. 20. 10. + BUTTON "Cancel" + ( + ; Reload the current config from disk + do currentconfig.cmm + + ; Close the dialog and reset the symbolics sourcepath + gosub CloseDialog + continue + ) + + //---------- Advanced/Basic Button ---------- + pos 65. 20. 11. +ADV_BASIC: BUTTON "Toggle Advanced" "gosub ToggleDialogMode" +) + + ; Set a flag to indicate that the dialig is open, seeing that there doesn't seem to be + ; a way of querying T32 about it + &ConfigDialogOpen="true" + + ; Initialise any dialog controls that were not filled in automatically when creating the + ; dialog and enable or disable the advanced ones as appropriate + gosub SetupDialogDefaults + + RETURN + +//============================================================================== +LoadPlatformFromFile: + ENTRY &fileName + LOCAL &platform + + ; Load the platform configuration from the filename passed in, if any + if "&fileName"!="" + ( + if os.file(&fileName) + ( + do &fileName + ) + ) + else + ( + ; Otherwise see what the currently selected platform is in the platforms drop down and load its configuration + &platform=dialog.string(PLATFORM) + if os.file(&PlatformsDir\&platform\&UserConfigCmm) + ( + do &PlatformsDir\&platform\&UserConfigCmm + ) + else + ( + print "No platform specific user config defined; using blank defaults" + &Platform="&platform" + &RamImage="" + &RamAddr="0" + &RamImage1="" + &RamAddr1="0" + &RamImage2="" + &RamAddr2="0" + &RamImage3="" + &RamAddr3="0" + &RamImage4="" + &RamAddr4="0" + ) + ) + + ; And re-open the dialog so that it displays the newly loaded configuration + gosub CloseDialog + gosub OpenDialog + + return + +//============================================================================== +SetAdvancedDialogOptions: + + dialog.enable LIST_SOURCEPATHS + dialog.enable EDIT_SOURCEPATHS + dialog.enable RELOAD_SOURCEPATHS + dialog.enable DEFAULT_SOURCEPATHS + dialog.enable SAVE_SOURCEPATHS + dialog.enable AUTOLOAD_MODULE + dialog.enable RAMADDR1 + dialog.enable RAMADDR2 + dialog.enable RAMADDR3 + dialog.enable RAMADDR4 + dialog.enable FLASHADDR + dialog.enable FLASHIMAGE + dialog.enable GETFLASHIMAGE + dialog.enable FLASHWRITEPROTECT + dialog.enable FLASHERASEPROTECT + &dialogMode="advanced" + + return + +//============================================================================== +SetBasicDialogOptions: + + dialog.disable LIST_SOURCEPATHS + dialog.disable EDIT_SOURCEPATHS + dialog.disable RELOAD_SOURCEPATHS + dialog.disable DEFAULT_SOURCEPATHS + dialog.disable SAVE_SOURCEPATHS + dialog.disable AUTOLOAD_MODULE + dialog.disable RAMADDR1 + dialog.disable RAMADDR2 + dialog.disable RAMADDR3 + dialog.disable RAMADDR4 + dialog.disable FLASHADDR + dialog.disable FLASHIMAGE + dialog.disable GETFLASHIMAGE + dialog.disable FLASHWRITEPROTECT + dialog.disable FLASHERASEPROTECT + &dialogMode="basic" + + return + +/============================================================================== +ToggleDialogMode: + + if ("&dialogMode"=="advanced") + ( + gosub SetBasicDialogOptions + ) + else + ( + gosub SetAdvancedDialogOptions + ) + + return + +//============================================================================== +CloseDialog: + ENTRY &save + + if ("&save"=="save") + ( + ; Read the dialog controls that might have changed and save the configuration to disk + gosub ReadDialog + gosub SavePlatformToFile "¤tConfigFile" + do PrintConfig.cmm + ) + + ; This function can be called safely even if the dialog is not open. To allow this we must + ; manually keep track of whether the dialog is open, as T32 will give an error if you try to + ; close a dialog that is not open + if "&ConfigDialogOpen"!="false" + ( + &ConfigDialogOpen="false" + dialog.end + ) + + return + +//============================================================================== +SetupDialogDefaults: + + ; Display or hide the advanced controls according to the user's preference + if ("&dialogMode"=="advanced") + ( + gosub SetAdvancedDialogOptions + ) + else + ( + gosub SetBasicDialogOptions + ) + + ; And initialise any not yet initialised controls to their default + dialog.set PLATFORM "&Platform" + dialog.set AUTOLOAD_MODULE "&AutoloadModule" + dialog.set RAMADDR1 "&RamAddr1" + dialog.set RAMIMAGE1 "&RamImage1" + dialog.set RAMADDR2 "&RamAddr2" + dialog.set RAMIMAGE2 "&RamImage2" + dialog.set RAMADDR3 "&RamAddr3" + dialog.set RAMIMAGE3 "&RamImage3" + dialog.set RAMADDR4 "&RamAddr4" + dialog.set RAMIMAGE4 "&RamImage4" + dialog.set FLASHADDR "&FlashAddr" + dialog.set FLASHIMAGE "&FlashImage" + dialog.set FLASHERASEPROTECT "&FlashEraseProtect" + dialog.set FLASHWRITEPROTECT "&FlashWriteProtect" + + + return + +//============================================================================== +ReadDialog: + + // Read dialog box config into global environment variables + &Platform=dialog.string(PLATFORM) + &AutoloadModule=dialog.string(AUTOLOAD_MODULE) + &RamImage1=dialog.string(RAMIMAGE1) + &RamAddr1=dialog.string(RAMADDR1) + &RamImage2=dialog.string(RAMIMAGE2) + &RamAddr2=dialog.string(RAMADDR2) + &RamImage3=dialog.string(RAMIMAGE3) + &RamAddr3=dialog.string(RAMADDR3) + &RamImage4=dialog.string(RAMIMAGE4) + &RamAddr4=dialog.string(RAMADDR4) + &FlashAddr=dialog.string(FLASHADDR) + &FlashImage=dialog.string(FLASHIMAGE) + + if "&RamImage"=="" + ( + &RamImage="&RamImage1" + &RamAddr="&RamAddr1" + ) + &FlashEraseProtect=dialog.boolean(FLASHERASEPROTECT) + if dialog.boolean(FLASHERASEPROTECT)==(0==0) + ( + &FlashEraseProtect="ON" + ) + else + ( + &FlashEraseProtect="OFF" + ) + + &FlashWriteProtect=dialog.boolean(FLASHWRITEPROTECT) + if dialog.boolean(FLASHWRITEPROTECT)==(0==0) + ( + &FlashWriteProtect="ON" + ) + else + ( + &FlashWriteProtect="OFF" + ) + + ; Make sure that target addresses have been specified and if not, use a sensible default that will + ; work on at least some platforms + if ("&RamAddr1"=="") + ( + &RamAddr1="0x80000000" + ) + + if ("&RamAddr2"=="") + ( + &RamAddr2="0x80000000" + ) + + if ("&RamAddr3"=="") + ( + &RamAddr3="0x80000000" + ) + + if ("&RamAddr4"=="") + ( + &RamAddr4="0x80000000" + ) + + if ("&FlashAddr"=="") + ( + &FlashAddr="0" + ) + + return + +//============================================================================== +SavePlatformToFile: + ENTRY &filename + + gosub ReadDialog + + // Open the config file for writing + open #1 &filename /Create + + // Write the config to the file in script format for loading later + write #1 "&"+"Platform="+'"'+"&Platform"+'"' + write #1 "&"+"AutoloadModule="+'"'+"&AutoloadModule"+'"' + write #1 "&"+"RamAddr="+'"'+"&RamAddr"+'"' + write #1 "&"+"RamImage="+'"'+"&RamImage"+'"' + write #1 "&"+"RamAddr1="+'"'+"&RamAddr1"+'"' + write #1 "&"+"RamImage1="+'"'+"&RamImage1"+'"' + write #1 "&"+"RamAddr2="+'"'+"&RamAddr2"+'"' + write #1 "&"+"RamImage2="+'"'+"&RamImage2"+'"' + write #1 "&"+"RamAddr3="+'"'+"&RamAddr3"+'"' + write #1 "&"+"RamImage3="+'"'+"&RamImage3"+'"' + write #1 "&"+"RamAddr4="+'"'+"&RamAddr4"+'"' + write #1 "&"+"RamImage4="+'"'+"&RamImage4"+'"' + write #1 "&"+"FlashAddr="+'"'+"&FlashAddr"+'"' + write #1 "&"+"FlashImage="+'"'+"&FlashImage"+'"' + write #1 "&"+"FlashWriteProtect="+'"'+"&FlashWriteProtect"+'"' + write #1 "&"+"FlashEraseProtect="+'"'+"&FlashEraseProtect"+'"' + + // All done, so close the file + close #1 + + // Do any tidyup + // type &filename + + RETURN + + +//============================================================================== +SavePlatform: + + //gosub PrintSeperator + //print "saving platform "+dialog.string(PLATFORM) + + // Open the config file for writing + &filename="&PlatformsDir\"+dialog.string(PLATFORM)+"\&UserConfigCmm" + + print "Saving platform to &filename" + gosub SavePlatformToFile &filename + RETURN + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// GeneratePlatformList +// +// Generate the list of platforms from a directory listing of the platforms +// script dir. +// +////////////////////////////////////////////////////////////////////////////// +GeneratePlatformList: + LOCAL &data + LOCAL &dirList + LOCAL &blanks + + &filename="&TMPDIR\platformList.txt" + prt.file &filename + winprint.dir &PlatformsDir + + &blanks=0 + open #1 &filename /Read + + // discard first line as it is the header & directory name + READ #1 %line &data + + // read the file line at a time, process it and add directory entries to the list of supported platforms + RePeaT + ( + READ #1 %line &data + + ; Okay, this is because there isn't a way of the read returning EOF + ; the easiest solution is to count the number of blank lines and if + ; it crosses a threshold assume that the end was reached. + if "&data"=="" + ( + &blanks=&blanks+1 + if &blanks>10 + ( + goto endloop + ) + ) + + // Remove all dots + gosub ReplaceAll "&data" "." "" + entry &tmp + &data=&tmp + + // Replace multiple spaces with one space + gosub ReplaceAll "&data" " " " " + entry &tmp + &data=&tmp + + // Remove leading spaces + gosub RemoveLeadingChars "&data" " " + entry &tmp + &data=&tmp + + // Replace all spaces with a comma + gosub ReplaceAll "&data" " " "," + entry &tmp + &data=&tmp + + if ("&dirList"=="") + ( + &dirList="&data" + ) + else + ( + &dirList="&dirList,&data" + ) + ) +endloop: CLOSE #1 + + &platformList="&dirList" + + RETURN + + + + + + +////////////////////////////////////////////////////////////////////////////// +// +// +// +////////////////////////////////////////////////////////////////////////////// +RemoveLeadingChars: + LOCAL &inStr &removeStr &pos1 &pos2 &outStr + ENTRY &inStr &removeStr + +// print "REMOVE: &inStr &removeStr" + + &pos1=string.scan(&inStr,&removeStr,0) +// print "pos1=&pos1" + + if (&pos1==0) + ( +// print "found!!!!!!!!" + + &len1=string.len(&inStr) + &len2=string.len(&removeStr) + +// print "len1=&len1" +// print "len2=&len2" + + &start=string.mid("&inStr",0,&pos1+1) + &end=string.mid("&inStr",&pos1+&len2+1,&len1) + +// print "start : &start" +// print "end : &end" + + &outStr="&start&end" +// print "outStr: &outStr" + ) + else + ( + &outStr="&inStr" + + ) + return &outStr + + +////////////////////////////////////////////////////////////////////////////// +// +// ReplaceAll +// +// Repeatedly call ReplaceInString to replace all occurrences of a given +// string (removeStr) with the new string (removeStr). +// +// Parameters: +// &inStr original string where replacements should be made +// &removeStr string to remove +// &replaceStr string to add in replacement for &removeStr +// +// Returns: +// string, in quotes. These quotes have to be stripped off to make the +// returned string useful. +// +// Example usage: +// +// &spaceStr="1 2 3 4 5 6 7 8 9" +// gosub ReplaceAll "&spaceStr" " " "," +// entry &retStr // this string has extra quotes +// &commaStr=&retStr // this strips the extra quotes from the string +// +// The expected output will be: +// "1,2,3,4,5,6,7,8,9" +// +////////////////////////////////////////////////////////////////////////////// +ReplaceAll: + ENTRY &inStr &removeStr &replaceStr + + LOCAL &ret + + repeat + ( + gosub ReplaceInString &inStr &removeStr &replaceStr + entry &ret + + if (&inStr==&ret) + ( + goto allreplaced + ) + &inStr="&ret" + ) +allreplaced: + return &inStr + + +////////////////////////////////////////////////////////////////////////////// +// +// ReplaceInString +// +// Within a given string (inStr), replace a single instance of a +// string (removeStr) with a new string (replaceStr). +// +// Parameters: +// &inStr original string where replacements should be made +// &removeStr string to remove +// &replaceStr string to add in replacement for &removeStr +// +// Returns: +// string, in quotes. These quotes have to be stripped off to make the +// returned string useful. +// +// Example usage: +// &spaceStr="1 2 3 4 5 6 7 8 9" +// gosub ReplaceInString &spaceStr " " "," +// entry &ret +// &commaStr=&ret +// +// The expected output will be: +// "1,2 3 4 5 6 7 8 9" +// +////////////////////////////////////////////////////////////////////////////// +ReplaceInString: + LOCAL &inStr &removeStr &pos1 &pos2 &outStr + ENTRY &inStr &removeStr &replaceStr + + &pos1=string.scan(&inStr,&removeStr,0) + + if (&pos1==-1) + ( + &outStr="&inStr" + ) + else + ( + &len1=string.len(&inStr) + &len2=string.len(&removeStr) + + &start=string.mid("&inStr",0,&pos1+1) + &middle=string.mid("&inStr",&pos1+1,&pos1+1+&len2) + &end=string.mid("&inStr",&pos1+&len2+1,&len1) + + &outStr="&start"+&replaceStr+"&end" + ) + return &outStr + + +//============================================================================== +GetImageFromUser: + ENTRY &dialogElement + + LOCAL &tmpRamImg + LOCAL &tmp1 + LOCAL &tmpfile + + &tmpRamImg=dialog.string(&dialogElement) + + &tmp1=os.file.path("&tmpRamImg")+"\"+"&defaultExt" + + dialog.file "&tmp1" + entry &tmpfile + if ("&tmpfile"!="") + ( + &tmpRamImg="&tmpfile" + + dialog.set &dialogElement "&tmpRamImg" + ) + return + +//============================================================================== +ListSourcePaths: + symbol.sourcepath.list + return + +//============================================================================== +ReloadSourcePaths: + do sourcepaths.cmm + return + +//============================================================================== +EditSourcePath: + + if os.file("&PlatformsDir\&Platform\customsourcepaths.cmm") + ( + print "Editing custom source paths" + ) + else + ( + if os.file("&PlatformsDir\&Platform\defaultsourcepaths.cmm") + ( + print "No custom source paths defined for this platform. Creating from default source paths." + copy &PlatformsDir\&Platform\defaultsourcepaths.cmm &PlatformsDir\&Platform\customsourcepaths.cmm + + // without this delay, the user gets prompted to reload the file + wait 0.5s + ) + ) + edit &PlatformsDir\&Platform\customsourcepaths.cmm + return + +//============================================================================== +DefaultSourcePaths: + if os.file("&PlatformsDir\&Platform\customsourcepaths.cmm") + ( + print "Removing custom source paths" + del &PlatformsDir\&Platform\customsourcepaths.cmm + ) + else + ( + print "Already using default source paths, nothing to do..." + ) + return + +//============================================================================== +SaveSourcePaths: + print "Saving custom source paths to file &PlatformsDir\&Platform\customsourcepaths.cmm" + store &PlatformsDir\&Platform\customsourcepaths.cmm SPATH + return + diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/currentconfig.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/currentconfig.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,31 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +&Platform="ne1_tb" +&AutoloadModule="" +&RamAddr="0x80000000" +&RamImage="N:\sf\os\kernelhwsrv\kernel\eka\rombuild\FNE1_TBARMV5SMP-ALLTESTS-D.IMG" +&RamAddr1="0x80000000" +&RamImage1="N:\sf\os\kernelhwsrv\kernel\eka\rombuild\FNE1_TBARMV5SMP-ALLTESTS-D.IMG" +&RamAddr2="0x80000000" +&RamImage2="N:\sf\os\kernelhwsrv\kernel\eka\rombuild\FNE1_TBARMV5SMP-AUTOTEST-D.IMG" +&RamAddr3="0x80000000" +&RamImage3="N:\sf\os\kernelhwsrv\kernel\eka\rombuild\NE1_TBARMV5-AUTOTEST-D.IMG" +&RamAddr4="0x80000000" +&RamImage4="N:\sf\os\kernelhwsrv\kernel\eka\rombuild\FNE1_TBARMV5-AUTOTEST-D.IMG" +&FlashAddr="0" +&FlashImage="X:\sf\os\kernelhwsrv\kernel\eka\rombuild\NE1_TBARMV5D-BOOTLDR-FAT32-D.IMG" +&FlashWriteProtect="ON" +&FlashEraseProtect="ON" diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/devboards_menus.men --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/devboards_menus.men Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,110 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +;******************************************************************************** +;* +;* devboards_menu.men +;* +;* Generic RAM download script with automatic attaching and symbol loading. +;* +;******************************************************************************** + +;******************************************************************************** +;* Devboards dropdown menu +;******************************************************************************** +ADD +MENU + ( + POPUP "&Devboards" + ( + MENUITEM "[:symbols]Enable Symbols" + ( + ChDir.DO ..\scripts-v2\attach.cmm + ChDir.DO ..\scripts-v2\symbolics.cmm + ) + MENUITEM "[:find]Toggle EKA2 awareness" "DO ..\scripts-v2\Toggle_SymbianAwareness.cmm" + + MENUITEM "[:list]List Symbol Modules" "symbol.autoload.list" + + ; ============================================================================== + SEPARATOR + MENUITEM "[:image]Config Dialog" "chdir.DO ..\scripts-v2\configdialog.cmm" + MENUITEM "[:right]Attach to board" "chdir.DO ..\scripts-v2\attach.cmm" + MENUITEM "[:left]Attach to board with Symbols" + ( + ChDir.DO ..\scripts-v2\attach.cmm + ChDir.DO ..\scripts-v2\symbolics.cmm + ) + MENUITEM "[:init]Init board" "chdir.DO ..\scripts-v2\init.cmm" + MENUITEM "[:load]Load Image to board" "chdir.DO ..\scripts-v2\load.cmm" + MENUITEM "[:symbols]Enable Symbols" "chdir.DO ..\scripts-v2\symbolics.cmm" + + SEPARATOR + + MENUITEM "[:load]Set image 1 as current image" "chdir.DO ..\scripts-v2\setimage.cmm 1" + MENUITEM "[:load]Set image 2 as current image" "chdir.DO ..\scripts-v2\setimage.cmm 2" + MENUITEM "[:load]Set image 3 as current image" "chdir.DO ..\scripts-v2\setimage.cmm 3" + MENUITEM "[:load]Set image 4 as current image" "chdir.DO ..\scripts-v2\setimage.cmm 4" + + SEPARATOR + + MENUITEM "[:flash]Erase Flash on board" "chdir.DO ..\scripts-v2\flasherase.cmm" + MENUITEM "[:flash]Flash Image to board" "chdir.DO ..\scripts-v2\flashimage.cmm" + ; ============================================================================== + SEPARATOR + MENUITEM "[:remove]Detach" "sys.down" + + SEPARATOR + + popup "H&2" + ( + ; These will only work on H2 + menuitem "View FrameBuffer 8BPP" "data.image asd:0x20002200 240. 320. /PALETTE256X12 asd:0x20002000" + menuitem "View FrameBuffer 16BPP" "data.image asd:0x20002200 240. 320. /RGB565LE" + ) + + POPUP "H&4" + ( + ; These will only work on H4 + MENUITEM "View FrameBuffer 16 BPP" + ( + ; Read the location of the framebuffer out of the display controller + local &_FRAMEBUFFERADDR + &_FRAMEBUFFERADDR=data.long(asd:0x48050480) + data.image asd:&_FRAMEBUFFERADDR 240. 320. // RGB565LE + ) + + MENUITEM "View FrameBuffer 24 BPP" + ( + ; Read the location of the framebuffer out of the display controller + local &_FRAMEBUFFERADDR + &_FRAMEBUFFERADDR=data.long(asd:0x48050480) + data.image asd:&_FRAMEBUFFERADDR 240. 320. // RGBX888LE + ) + + MENUITEM "View FrameBuffer 16 BPP Landscape" + ( + ; Read the location of the framebuffer out of the display controller + local &_FRAMEBUFFERADDR + &_FRAMEBUFFERADDR=data.long(asd:0x48050480) + data.image asd:&_FRAMEBUFFERADDR 320. 240. // RGB565LE + ) + ) + + SEPARATOR + MENUITEM "Edit menus" "b::menu.program ..\scripts-v2\devboards_menus.men" + MENUITEM "Refresh menus" "b::menu.reprogram ..\scripts-v2\devboards_menus.men" + ) + ) diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/devboards_toolbar.men --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/devboards_toolbar.men Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,81 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +; MENU file toolbar +; link this into t32.cmm for it to autoload when you start trace 32 +; menu.reprogram c:\t32\scripts-v2\devboards_menus.men +; +; edit with : b::menu.program devboards_menus.men +; NOTE!! contains an absolute paths of ".." Simon's system has various +; versions of Trace32 installed in c:\t32\ under subdirectories and this +; menu file and the scripts installed within the c:\t32\ root. + +ADD +TOOLBAR +( + ; ============================================================================== + SEPARATOR +; TOOLITEM "MMU ON" ":map" +; ( +; mmu.reset +; mmu.scan 0x0:0x0--0xffffffff +; mmu.cleanup +; mmu.on +; ) + TOOLITEM "Use on-chip breakpoints" ":breaknew" "break.select.program onchip" + TOOLITEM "Browse Symbols" ":varref" "symbol.browse.function \\*" + TOOLITEM "Show code pointed to by R14SVC" ":symbols" "data.list register(R14_svc)" + TOOLITEM "Show *this" "*t" "var.view *this" + + ; ============================================================================== + SEPARATOR + TOOLITEM "Config Dialog" ":image" "chdir.DO ..\scripts-v2\configdialog.cmm" + TOOLITEM "Attach to board" "A" "chdir.DO ..\scripts-v2\attach.cmm" + TOOLITEM "Attach to board with Symbols" "AS" + ( + ChDir.DO ..\scripts-v2\attach.cmm + ChDir.DO ..\scripts-v2\symbolics.cmm + ) + TOOLITEM "Init board" "I" "chdir.DO ..\scripts-v2\init.cmm" + TOOLITEM "Load Image to board" "L" + ( + chdir.DO ..\scripts-v2\load.cmm + ) + TOOLITEM "Enable Symbols" "SY" "chdir.DO ..\scripts-v2\symbolics.cmm" + SEPARATOR + TOOLITEM "Set image 1 as current image" "1" + ( + chdir.DO ..\scripts-v2\setimage.cmm 1 + ) + TOOLITEM "Set image 2 as current image" "2" + ( + chdir.DO ..\scripts-v2\setimage.cmm 2 + ) + TOOLITEM "Set image 3 as current image" "3" + ( + chdir.DO ..\scripts-v2\setimage.cmm 3 + ) + TOOLITEM "Set image 4 as current image" "4" + ( + chdir.DO ..\scripts-v2\setimage.cmm 4 + ) + SEPARATOR + TOOLITEM "Erase Flash on board" "FE" "chdir.DO ..\scripts-v2\flasherase.cmm" + TOOLITEM "Flash Image to board" "FI" "chdir.DO ..\scripts-v2\flashimage.cmm" + ; ============================================================================== + SEPARATOR + TOOLITEM "Detach" ":remove" "sys.down" +) + diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/flasherase.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/flasherase.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,65 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// Generic NOR Flash erasing script. +// +// Change History: +// +// 01/01/2008 1.0 : Initial version +// 08/05/2009 1.1 : Updated to fit in with new platform specific flashing mechanism +// +////////////////////////////////////////////////////////////////////////////// + +&scriptversion=1.1 + +print "=======================================================================" +print "Generic NOR flash erasing script version &scriptversion" + +; Declare the global variables used by the system and read the current config into them +do globals.cmm + +; Make sure that flashing is supported on the target platform +if os.file("&PlatformsDir\&Platform\flash.cmm") + ( + ; Get some generic global settings before doing anything + do init.cmm + + local &result + + ; Make sure the user really does want to wipe out their NOR flash! + if "&FlashEraseProtect"!="OFF" + ( + dialog.yesno "Are you *sure* you want to erase NOR flash?" + entry &result + ) + else + ( + &result=(0==0) + ) + + if &result + ( + ; Now do the platform specific operations + do &PlatformsDir\&Platform\flasherase.cmm + ) + ) +else + ( + dialog.ok "NOR flashing not supported for platform &Platform" + ) + +enddo diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/flashimage.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/flashimage.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,98 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// Generic NOR Flash writing script. +// +// Change History: +// +// 01/01/2008 1.0 : Initial version +// 12/02/2009 1.1 : Updated to initialise board and load globals before doing +// anything else +// +////////////////////////////////////////////////////////////////////////////// + +&scriptversion=1.1 + +print "=======================================================================" +print "Generic NOR flashing script version &scriptversion" + +; Declare the global variables used by the system and read the current config into them +do globals.cmm + +; Make sure that flashing is supported on the target platform +if os.file("&PlatformsDir\&Platform\flash.cmm") + ( + local &result + + ; Make sure the user really does want to overwrite out their NOR flash! + if "&FlashWriteProtect"!="OFF" + ( + dialog.yesno "Are you *sure* you want to erase NOR flash and write this image: &FlashImage?" + entry &result + ) + else + ( + &result=(0==0) + ) + + if &result + ( + ; Attach to the board and reset its hardware completely + do init.cmm + + ; Make sure a filename has been specified + if "&FlashImage"=="" + ( + print "Select ROM image to flash" + + dialog.file "*.bin;*.img" + entry &FlashImage + + if "&FlashImage"=="" + ( + print "*** Aborted (no ROM image filename specified) ***" + enddo + ) + ) + + print "&Platform hardware configured for flashing" + + ; Load first few bytes of the image into ram and see whether it has an EPOC header on the front + data.load.binary "&FlashImage" &RamAddr++0x200 + &firstWord=(data.long(sd:&RamAddr)) + &skipHeader="false" + + if ((&firstWord)==0x434F5045) + ( + print "File &FlashImage has EPOC header (will skip it)" + &skipHeader="true" + ) + else + ( + print "No EPOC header present on file &FlashImage" + ) + + ; Now do the platform specific operations + do &PlatformsDir\&Platform\flash.cmm "&FlashImage" &FlashAddr &skipHeader + ) + ) +else + ( + dialog.ok "NOR flashing not supported for platform &Platform" + ) + +enddo diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/globals.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/globals.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,117 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// Defines all of the global variables that represent the boards that the T32 +// script system supports, and the paths to the ROM images for those boards. +// This is designed to be used in conjunction with the board configuration +// system to be found in configdialog.cmm. +// +////////////////////////////////////////////////////////////////////////////// + +// General Globals +GLOBAL &_BASELOC +GLOBAL &PlatformsDir +GLOBAL &TMPDIR +GLOBAL &UserConfigCmm + +// User's Platform Config +GLOBAL &Platform +GLOBAL &AutoloadModule +GLOBAL &RamAddr +GLOBAL &RamImage +GLOBAL &RamAddr1 +GLOBAL &RamImage1 +GLOBAL &RamAddr2 +GLOBAL &RamImage2 +GLOBAL &RamAddr3 +GLOBAL &RamImage3 +GLOBAL &RamAddr4 +GLOBAL &RamImage4 +GLOBAL &FlashAddr +GLOBAL &FlashImage +GLOBAL &FlashWriteProtect +GLOBAL &FlashEraseProtect +GLOBAL &BootAddr +GLOBAL &BootImage + +// Platform Config +// Generic Trace32 settings +GLOBAL &CpuType +GLOBAL &JtagClock +GLOBAL &NumberOfCpus + +// On Chip Triggers +GLOBAL &OnChipTriggerFiq +GLOBAL &OnChipTriggerIrq +GLOBAL &OnChipTriggerDabort +GLOBAL &OnChipTriggerPabort +GLOBAL &OnChipTriggerSwi +GLOBAL &OnChipTriggerUndef +GLOBAL &OnChipTriggerReset +GLOBAL &OnChipTriggerAlignment +GLOBAL &OnChipTriggerStepvector +GLOBAL &OnChipTriggerAddress +GLOBAL &OnChipTriggerError + + +// System Options +GLOBAL &SystemOptionEnreset +GLOBAL &SystemOptionTurbo +GLOBAL &SystemOptionDismode +GLOBAL &SystemOptionNoircheck +GLOBAL &SystemOptionWaitreset +GLOBAL &SystemOptionResbreak +GLOBAL &SystemOptionDacr +GLOBAL &SystemOptionTidbgen +GLOBAL &SystemOptionPwrCheck +GLOBAL &SystemOptionNoSecureFix + +// Flash options +GLOBAL &FlashType +GLOBAL &FlashBlockSize +GLOBAL &FlashStart +GLOBAL &FlashLength +GLOBAL &FlashEnd +GLOBAL &FlashWidth +GLOBAL &FlashOptionTarget + +GLOBAL &SystemConfigCorebase0 +GLOBAL &SystemConfigCorebase1 +GLOBAL &SystemConfigCtibase0 +GLOBAL &SystemConfigCtibase1 +GLOBAL &SystemConfigEtmfunnelport +GLOBAL &SystemConfigFunnelbase +GLOBAL &SystemConfigEtmbase +GLOBAL &SystemConfigEtbbase +GLOBAL &SystemConfigTpiubase + +////////////////////////////////////////////////////////////////////////////// +// Set the global config +////////////////////////////////////////////////////////////////////////////// +&PlatformsDir="Platforms" +&TMPDIR=os.ptd() +&UserConfigCmm="userconfig.cmm" + +if os.file("currentconfig.cmm") + ( + do currentconfig.cmm + ) + +if os.file("&PlatformsDir\&Platform\platformconfig.cmm") +( + do &PlatformsDir\&Platform\platformconfig.cmm +) diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/init.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/init.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,63 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// This script will attach to the board for debugging and will perform a full +// hardware initialisation on it. It is designed to be used in conjunction +// with the board configuration system to be found in configdialog.cmm. +// +// Change History: +// +// 01/01/2008 1.0 : Initial version +// 12/05/2009 1.1 : Tidied up in readiness for putting into Nokia's distribution system +// +////////////////////////////////////////////////////////////////////////////// + +&scriptversion=1.1 + +print "=======================================================================" +print "Generic initialisation script version &scriptversion" + +; Declare the global variables used by the system and read the current config into them +do globals.cmm + +; Reset t32 symbolics +system.reset + +; Clear all breakpoints +break.reset + +; Turn on spotlight everywhere +setup.var.%SPOTLIGHT.on + +; Do the platform specific operations to attach to the board +if os.file("&PlatformsDir\&Platform\attach.cmm") + ( + do &PlatformsDir\&Platform\attach.cmm + ) +else + ( + print "No platform specific attach script available, trying generic attaching" + sys.mode.attach + ) + +; Now do the platform specific operations to reset the board's hardware +if os.file("&PlatformsDir\&Platform\init.cmm") + ( + do &PlatformsDir\&Platform\init.cmm + ) + +enddo diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/load.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/load.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,154 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// Generic ROM image loading script with automatic attaching and symbol loading. +// This is designed to be used in conjunction with the board configuration +// system to be found in configdialog.cmm. +// +////////////////////////////////////////////////////////////////////////////// + +print "=======================================================================" +print "Generic ROM image loading script" + +; Declare the global variables used by the system and read the current config into them +do globals.cmm + +; Special check so that people do not try to download images to the h6 or labrador, which is not supported +if ("&Platform"=="34xx_sdp"||"&Platform"=="34xx_lab") + ( + dialog.ok "Image downloading not supported for &Platform" + enddo + ) + +if "&RamImage"=="" + ( + print "No image selected" + enddo + ) + +; Attach to the board and reset its hardware completely +do init.cmm + +; Clean up some image specific details +task.reset +mmu.reset + +; Detected from image file +&fileName="&RamImage" +&fileSize=os.file.size(&fileName) +&fileDate=os.file.date(&fileName) + +print "=========================================================" +print "Filename: &fileName" +print "Date: &fileDate" +print "Size: &fileSize" +print "RAM addr: &RamAddr" +print "=========================================================" + +; Load first few bytes of the image into ram and see whether it has a header on the front +data.load.binary "&fileName" &RamAddr++0x200 +&firstWord=(data.long(sd:&RamAddr)) +&skipHeader="false" + +if ((&firstWord)==0x434F5045) + ( + print "File has EPOC Image header (will skip it)" + &skipHeader="true" + ) +else + ( + print "No EPOC header present on file &fileName" + ) + +print "Started download: " CLOCK.TIME() + +; Turbo mode will disable cpu checks after each system speed memory access +if ("&SystemOptionTurbo"!="") + ( + sys.option turbo &SystemOptionTurbo + ) + +; Udate the screen +screen + +if "&skipHeader"=="true" + ( + data.load.binary "&fileName" &RamAddr /SKIP 100 + ) +else + ( + data.load.binary "&fileName" &RamAddr + ) + +if os.file("&PlatformsDir\&Platform\postload.cmm") + ( + do &PlatformsDir\&Platform\postload.cmm + ) + +sys.option turbo off + +print "Finished load: " CLOCK.TIME() + +; Set all CPUs to point at the entrypoint of the ROM, stored in RamAddr +¤tCPU=&NumberOfCpus-1 +print "Setting PC of &NumberOfCpus CPU core(s) to &RamAddr" + +while ¤tCPU>=0 + ( + ; Only change the current core if there is more than one or it will cause an error + if &NumberOfCpus>1 + core ¤tCPU + + ; Now set the PC address for the current core + register.set PC &RamAddr + ¤tCPU=¤tCPU-1 + ) + +; How do we decide whether this is a debug image or not? if we check for a 'D' +; in the filename it could match on anything whilst if we match on *D.IMG we'll +; get most of the debug images but not all of them... +if string.scan(string.lwr("&fileName"),"techview.img",0)==-1 + ( + ; Logic doesn't work for Techview + if string.scan(string.lwr("&fileName"),"d.img",0)==-1 + ( + ; .SYM files are not normally produced for UREl builds, but we might have a .SYMBOL + ; file that we can pull in. See if there is a .symbol file matching the filename. + &_SYMBOLBASENAME=string.cut("&fileName",-string.len(os.file.extension(&fileName))) + &_SYMBOLFILENAME="&_SYMBOLBASENAME"+".symbol" + if os.file("&_SYMBOLFILENAME") + ( + ; This was recently added by Lauterbach so it is not in all versions of the software + data.load.symbian "&_SYMBOLFILENAME" &RamAddr /nocode + print "UREL image, .symbol file loaded, finished everything: " CLOCK.TIME() + ENDDO + ) + + print "UREL image, no .symbol file, finished everything: " CLOCK.TIME() + enddo + ) + ) + +; Switch the windows in to showing source (if available) rather than mixed +mode.hll + +; Sase disassemble method on symbol data rather than CPU access mode +sys.OPTION DISMODE AUTO + +do symbolics.cmm + +enddo diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/printconfig.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/printconfig.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,89 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// A script to display the current configuration of T32, in terms of what board +// it is configured for and the ROM image to be used etc. This can be called by +// the configdialog.cmm script or manually by the user. +// +// Change History: +// +// 11/11/2008 1.0 : Initial version +// 13/05/2009 1.1 : Tidied up in readiness for putting into Nokia's distribution system +////////////////////////////////////////////////////////////////////////////// + +&scriptversion=1.1 + +; Make sure that we have loaded the latest configuration variables +do globals.cmm + +print "==============================================================================" +print "USER CONFIG" +print "==============================================================================" + +print "Platform &Platform" +print "RAM Addr &RamAddr" +print "RAM Image &RamImage" +print "Flash Addr &FlashAddr" +print "Flash Image &FlashImage" +print "Boot Addr &BootAddr" +print "Boot Image &BootImage" +print "Flash Write Protect &FlashWriteProtect" +print "Flash Erase Protect &FlashEraseProtect" + +print "==============================================================================" +print "PLATFORM CONFIG" +print "==============================================================================" + +print "CPU Type &CpuType" +print "JTAG clock &JtagClock" +print "Number of CPUs &NumberOfCpus" + +print "On-chip triggers->" +print " FIQ &OnChipTriggerFiq" +print " IRQ &OnChipTriggerIrq" +print " DABORT &OnChipTriggerDabort" +print " PABORT &OnChipTriggerPabort" +print " SWI &OnChipTriggerSwi" +print " UNDEF &OnChipTriggerUndef" +print " RESET &OnChipTriggerReset" +print " Alignment &OnChipTriggerAlignment" +print " StepVector &OnChipTriggerStepvector" +print " ADDRESS &OnChipTriggerAddress" +print " ERROR &OnChipTriggerError" + +print "Sytem Option ->" +print " enreset &SystemOptionEnreset" +print " turbo &SystemOptionTurbo" +print " dismode &SystemOptionDismode" +print " noircheck &SystemOptionNoircheck" +print " waitreset &SystemOptionWaitreset" +print " resbreak &SystemOptionResbreak" +print " dacr &SystemOptionDacr" +print " tidbgen &SystemOptionTidbgen" + +print "Flash Config" +print " Type &FlashType" +print " Bloc Size &FlashBlockSize" +print " Start Addr &FlashStart" +print " Length &FlashLength" +print " End Addr &FlashEnd" +print " Width &FlashWidth" +print " Target &FlashOptionTarget" + +print "==============================================================================" + +enddo diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/setimage.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/setimage.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,46 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// Updates the current config with the image details of the image number +// supplied +////////////////////////////////////////////////////////////////////////////// + +entry &imageNum + +if "&imageNum"=="4" +( +&RamImage="&RamImage4" +&RamAddr="&RamAddr4" +) +else if "&imageNum"=="3" +( +&RamImage="&RamImage3" +&RamAddr="&RamAddr3" +) +else if "&imageNum"=="2" +( +&RamImage="&RamImage2" +&RamAddr="&RamAddr2" +) +else +( +&RamImage="&RamImage1" +&RamAddr="&RamAddr1" +) + +do writecurrentconfig.cmm + +print "Image #&imageNum active: &RamImage" diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/sourcepaths.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/sourcepaths.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,82 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// This script configures the paths that are searched for source code to be a +// list of user specified paths plus a path that is computed as being the root +// of the environment, ie. The path at which the "os" directory resides. +// +////////////////////////////////////////////////////////////////////////////// + +GLOBAL &driveletter +GLOBAL &sospath + +&driveletter=string.mid(os.file.path(&_SYMBOLICS_FILENAME),0.,2.) +&sospath="" + +if os.file("&driveletter\os\kernelhwsrv\kernel\eka\release.txt") + ( + &sospath="" + ) +else if os.file("&driveletter\sf\os\kernelhwsrv\kernel\eka\release.txt") + ( + &sospath="\sf" + ) +else + ( + &sospath="" + ) +print "Base path for SymbianOS source code is &driveletter&sospath\os" + +if os.file("&PlatformsDir\&Platform\customsourcepaths.cmm") + ( + print "Loading custom source paths" + do &PlatformsDir\&Platform\customsourcepaths.cmm + ) +else + ( + if os.file("&PlatformsDir\&Platform\defaultsourcepaths.cmm") + ( + print "Loading default source paths for this platform" + do &PlatformsDir\&Platform\defaultsourcepaths.cmm + ) + else + ( + print "No source paths defined for this platform, using some generic ones" + + ; extract the drive letter and add it to the symbol path + &driveletter=string.mid(os.file.path(&_SYMBOLICS_FILENAME),0.,2.) + + SYMBOL.SPATH.RESET + SYMBOL.SPATH.SETRECURSEDIR "&driveletter&sospath\os\kernelhwsrv\kernel\eka\drivers" + if "&NumberOfCpus">"1" + ( + print "More than one CPU, so using NKernSMP, not NKern" + SYMBOL.SPATH.SETRECURSEDIR "&driveletter&sospath\os\kernelhwsrv\kernel\eka\nkernsmp" + SYMBOL.SPATH.SET "&driveletter\epoc32\release\armv5smp\UDEB" + ) + else + ( + print "Only one CPU, so using NKern, not NKernSMP" + SYMBOL.SPATH.SETRECURSEDIR "&driveletter&sospath\os\kernelhwsrv\kernel\eka\nkern" + ) + + SYMBOL.SPATH.SETRECURSEDIR "&driveletter&sospath\os\kernelhwsrv\kernel\eka\kernel" + SYMBOL.SPATH.SET "&driveletter\epoc32\release\armv5\UDEB" + ) + ) + +enddo diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/symbolics.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/symbolics.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,421 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// +// This script configures the autoloader for full symbolic debugging. It is +// designed to be used in conjunction with the board configuration system to +// be found in configdialog.cmm. +// +////////////////////////////////////////////////////////////////////////////// + +print "=======================================================================" +print "Generic symbol autoloader configuration script" + +global &_IS_BOOTLOADER +global &_T32ROMDIR +global &IsTextshell + +&IsTextshell=(0==1) + +if "&_IS_BOOTLOADER"=="" + ( + &_IS_BOOTLOADER=(0==1) + ) + +; Start from clean +symbol.reset +symbol.autoload.reset + +; Add some special labels to various addresses so if an exception occurs it will me +; immediately obvious as to what caused it +symbol.new.function VECTORS 0xFFFF0000++0x1C +symbol.new.label RESET 0xFFFF0000 +symbol.new.label UNDEF 0xFFFF0004 +symbol.new.label SWI 0xFFFF0008 +symbol.new.label PREFETCH_ABORT 0xFFFF000C +symbol.new.label DATA_ABORT 0xFFFF0010 +symbol.new.label IRQ 0xFFFF0018 +symbol.new.label FIQ 0xFFFF001C + +; Get the image filename +&_DIALOG_PATH=os.env(T32ROMDIR) + +if "&_DIALOG_PATH"=="" + ( + if "&_T32ROMDIR"=="" + ( + &_DIALOG_PATH="*.IMG" + ) + else + ( + &_DIALOG_PATH="&_T32ROMDIR"+"\*.IMG" + ) + ) +else + ( + &_DIALOG_PATH="&_DIALOG_PATH"+"\*.IMG" + ) + +local &_SYMBOLICS_FILENAME +&_SYMBOLICS_FILENAME="&RamImage" + +local &_SYMBOLICS_LOAD_ADDRESS +&_SYMBOLICS_LOAD_ADDRESS="&RamAddr" + +if "&_SYMBOLICS_FILENAME"=="" + ( + print "Select EPOC image that is currently running:" + + dialog.file &_DIALOG_PATH + entry &_SYMBOLICS_FILENAME + + if "&_SYMBOLICS_FILENAME"=="" + ( + ; disconnect from the board + print "*** Aborted (no ROM image filename specified) ***" + enddo + ) + ) + +; Check for a logfile with the same path and stem as the ROM name and if found use that. Failing +; that, check for a logfile with the same path but called romfile.log and if found, use that +&_LOGBASENAME=string.cut("&_SYMBOLICS_FILENAME",-string.len(os.file.extension(&_SYMBOLICS_FILENAME))) +&_LOGFILENAME="&_LOGBASENAME"+".log" + +if !os.file("&_LOGFILENAME") + ( + &_LOGFILENAME=string.cut("&_SYMBOLICS_FILENAME",-string.len(os.file.name(&_SYMBOLICS_FILENAME))) + &_LOGFILENAME="&_LOGFILENAME"+"rombuild.log" + + if !os.file("&_LOGFILENAME") + ( + print "*** Log file not found. Select logfile for this image ***" + &_DIALOG_PATH="&_SYMBOLICS_FILENAME"+"\*.log" + dialog.file &_DIALOG_PATH + entry &_LOGFILENAME + ) + ) + +if os.file("&_LOGFILENAME") + ( + print "Using &_LOGFILENAME for symbols" + ) +else + ( + print "*** Aborted (no logfile name specified) ***" + enddo + ) + +; It's possible that the script guesses a right logfilename but the user has let +; the log get out of date when compared to the image. Do a very quick compare on +; the timestamps - this will reject guessed filenames if the minute rolls over. +local &_DATE_IMAGE +local &_DATE_LOG + +&_DATE_IMAGE=string.cut(os.file.date(&_SYMBOLICS_FILENAME), -2) +&_DATE_LOG=string.cut(os.file.date(&_LOGFILENAME), -2) + +if "&_DATE_IMAGE"!="&_DATE_LOG" + ( + print "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + print "Would guess logfile was &_LOGFILENAME but not perfect time match" + print "Date image: &_DATE_IMAGE" + print "Date log: &_DATE_LOG" + print "Select rombuild.log for this image:" + print "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + &_DIALOG_PATH="&_SYMBOLICS_FILENAME"+"\*.log" + dialog.file &_DIALOG_PATH + entry &_LOGFILENAME + + if "&_LOGFILENAME"=="" + ( + print "*** Aborted (no logfile name specified) ***" + enddo + ) + + if os.file("&_LOGFILENAME") + ( + print "Now using &_LOGFILENAME for symbols" + ) + else + ( + print "*** Aborted (no logfile name specified) ***" + enddo + ) + ) + +; parse the rombuild.log file to extract the rom checksum +LOCAL &data &_BLANKS &_LOG_CHECKSUM +&_BLANKS=0 + +OPEN #1 &_LOGFILENAME /Read +REPEAT +( + READ #1 %line &data + ; Okay, this is because there isn't a way of the read returning EOF + ; the easiest solution is to count the number of blank lines and if + ; it crosses a threshold assume that the end was reached. + if "&data"=="" + ( + &_BLANKS=&_BLANKS+1 + if &_BLANKS>10 + ( + print "10 blank lines, assume EOF" + goto endloop + ) + ) + else + ( + &_BLANKS=0 + ) + + if (string.scan("&data", "bootldr",0)!=-1) + ( + &_IS_BOOTLOADER=(1==1) + ) + + if (string.scan("&data", "Checksum word:",0)!=-1) + ( + &_LOG_CHECKSUM=string.cut("&data", 25.) + goto endloop + ) +) +endloop: +CLOSE #1 + +if ("&_LOG_CHECKSUM"=="") + ( + print "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + print "Can't get checksum from rombuild.log - aborting" + print "Log: &_LOG_CHECKSUM" + print "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + enddo + ) + +if ("&_LOG_CHECKSUM"!="") + ( + &_LOG_CHECKSUM="0x"+string.upr("&_LOG_CHECKSUM") + ) + +; Get the checksum from the board. Yes, duplicating two lines - it takes more +; lines of code to do the conditionals and variables required to record state +; and it looks very strange +local &_ROM_CHECKSUM + +; TODO - Temporary hack to get around NaviEngine problems +if "&Platform"!="ne1_tb" + ( + if run() + ( + break + &_ROM_CHECKSUM=&_SYMBOLICS_LOAD_ADDRESS+0xA8 + &_ROM_CHECKSUM=data.long(ad:&_ROM_CHECKSUM) + go + ) + else + ( + &_ROM_CHECKSUM=&_SYMBOLICS_LOAD_ADDRESS+0xA8 + &_ROM_CHECKSUM=data.long(ad:&_ROM_CHECKSUM) + ) + + if (&_ROM_CHECKSUM!=&_LOG_CHECKSUM) + ( + print "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + print "Checksums don't match" + print "Rom: &_ROM_CHECKSUM" + print "Log: &_LOG_CHECKSUM" + print "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + ) + ) + +; Try and find the root of the source. This works relative to the "os" directory +; to take into account different source code layouts. It will work with substed +; and non substed drives, and with Perforce style and CBR style source layouts. +; +; The root is determined from the value of the fully qualified ROM name as setup +; in the &RamImage variable, as specified in the configdialog.cmm script. This is +; to take into account different source layouts and the fact that EPOCROOT may not +; be == \ + +local &epoc32 +local &os + +; Start by finding the "os" directory in the current qualified ROM name +print "Scanning "+os.file.path(&_SYMBOLICS_FILENAME)+" for os source directory" +&os=string.scan(os.file.path(&_SYMBOLICS_FILENAME),"os",0.) + +if (&os>=0x00) + ( + &_BASELOC=string.mid(os.file.path(&_SYMBOLICS_FILENAME),0,&os) + + if os.dir("&_BASELOC") + ( + &IsTextshell=(1==1) + print "Using path &_BASELOC as a relative path to source" + ) + else + ( + &_BASELOC="" + ) + ) +else + ( + ; Not found so assume we are using a CBR build and try for epoc32 + print "Scanning "+os.file.path(&_SYMBOLICS_FILENAME)+" for epoc32 directory" + &epoc32=string.scan(os.file.path(&_SYMBOLICS_FILENAME),"epoc32",0.) + + if (&epoc32>=0x00) + ( + &_BASELOC=string.mid(os.file.path(&_SYMBOLICS_FILENAME),0,&epoc32) + + if os.dir("&_BASELOC") + ( + print "Using path &_BASELOC as a relative path to source" + ) + else + ( + &_BASELOC="" + ) + ) + ) + +if "&_BASELOC"=="" + ( + print "No os source path found, guessing it is one of the usual ones..." + &_BASELOC="&driveletter\os" + if os.dir("&_BASELOC") + ( + ) + else + ( + &_BASELOC="&driveletter\sf\os" + ) + print "Using path &_BASELOC as a relative path to source" + ) + +&_AUTOLOAD="/autoload" ; handles arm4 and armv5 + +; Try to determine from the ROM name the CPU architecture is in use. If we can't then assume that it's +; the upcoming armv7 +local &_ARCH + +&flexible="" + +if string.scan(string.lwr("&_SYMBOLICS_FILENAME"),"arm4",0)!=-1 + ( + &_ARCH="arm4" + ) +else if string.scan(string.lwr("&_SYMBOLICS_FILENAME"),"armv5smp",0)!=-1 + ( + &_ARCH="armv5smp" + if ("&Platform"=="ne1_tb") + ( + print "Detected Flexible Memory Model for NaviEngine SMP image" + &flexible="f" + ) + ) +else if string.scan(string.lwr("&_SYMBOLICS_FILENAME"),"armv7",0)!=-1 + ( + &_ARCH="armv7" + ) +else + ( + &_ARCH="armv5" + if ("&Platform"=="ne1_tb"&&string.scan(string.lwr("&_SYMBOLICS_FILENAME"),"fne1_tb",0)!=-1) + ( + print "Detected Flexible Memory Model for NaviEngine unicore image" + &flexible="f" + ) + ) + +; Setup the source paths as determined automatically and also as specified by the user +do sourcepaths.cmm + +local &epocRoot +if os.dir("&driveletter\epoc32") +( + &epocRoot="&driveletter\" +) +else +( + &epocRoot="&_BASELOC" +) + +; Determine the name of the bootstrap binary, using special handling if this is a bootloader image +local &bootStrapFileName + +if &_IS_BOOTLOADER + ( + &bootStrapFileName="&epocRoot"+"epoc32\release\"+"&_ARCH"+"\_"+"&flexible&Platform"+"_bootloader_bootrom.bin" + ) +else + ( + &bootStrapFileName="&epocRoot"+"epoc32\release\"+"&_ARCH"+"\_"+"&flexible&Platform"+"_bootrom.bin" + ) + +; Determine whether to use SBSv1 or SBSv2 symbol file +local &symfilename + +do checksymbols.cmm "&bootStrapFileName" +if "&symfilename"!="" + ( + &bootStrapFileName="&symfilename" + ) + +; Scan rombuild log file for modules & addresses +symbol.AutoLoad.LOADEPOC &_LOGFILENAME "do "+os.ppd()+"&_AUTOLOAD " +symbol.AutoLoad.CHECKEPOC "do "+os.ppd()+"&_AUTOLOAD " ; define dynamic autoloader +symbol.AutoLoad.CHECK OFF ; switch off automatic process detection + +; If we are running a textshell image then we are probably a base engineer who has compile the image him +; or herself, so the kernel symbolics will be available. If so then load them now +if &IsTextshell + ( + symbol.autoload.touch "*ekern.exe*" + ) + +; If the user has specified to load symbols for a particular module, load them now +if "&AutoloadModule"!="" + ( + print "Autoloading symbols for &AutoloadModule" + symbol.autoload.touch "&AutoloadModule" + ) + +; Breakpoint on kernel faults - do this before any other symbol files get loaded +; otherwise it could match on stub functions +if (y.exist("Kern::Fault")) + ( + B.S Kern::Fault /P /ONCHIP + ) + +; Again, if we are running a textshell image then load the variant and bootstrap symbols +if &IsTextshell + ( + symbol.AutoLoad.TOUCH "*ecust*" + + if os.file(&bootStrapFileName) + ( + print "Loading bootstrap symbolics for &bootStrapFileName" + data.load.auto &bootStrapFileName &_SYMBOLICS_LOAD_ADDRESS /nocode /strippart 3 /noclear + ) + else + ( + print "*** Skipping bootstrap symbolics (can't find &bootStrapFileName) ***" + ) + ) + +symbol.cleanup +enddo diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/toggle_symbianawareness.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/toggle_symbianawareness.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,89 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +; script to toggle EKA2 Symbian OS awareness on and off safely +; 5/5/05 4.1 : modified script ordering so you can turn of awareness without +; being attached +; 4/5/05 4.0 : rolled version to 4.0 for release +; 7/4/05 1.0 : initial checkin + +; if os awareness is enabled, remove it and end +global &_SYMBIAN_OS_AWARENESS_ENABLED +if ("&_SYMBIAN_OS_AWARENESS_ENABLED"=="") + ( + &_SYMBIAN_OS_AWARENESS_ENABLED=(0==1) + ) + +if (&_SYMBIAN_OS_AWARENESS_ENABLED) + ( + print "Removing SymbianOS support..." + TASK.reset + local &_FILE_CHECK + &_FILE_CHECK="symbian2.t32" + if os.file(&_FILE_CHECK) + ( + MENU.delete symbian2 + ) + else + ( + MENU.delete c:\t32\demo\arm\kernel\symbian\eka2\symbian2 + ) + + &_SYMBIAN_OS_AWARENESS_ENABLED=(0==1) + + enddo + ) + +; check that symbols are enabled +if !(y.exist("KernelMain")) + ( + print "ERROR: You must have symbols turned on to enable SymbianOS awareness" + end + ) + +if run() + break + +; Sanity test +; check that the mmu is on +if (Data.Long(C15:0x1)&0x1)==0 + ( + &local _CP15 + &_CP15=data.long(C15:0x1) + print "ERROR: MMU is not enabled => to enable symbian awareness you must boot the system (CP15=&_CP15)" + end + ) + +; enable os awareness +print "Initialising SymbianOS support..." + +TASK.RESET +local &_FILE_CHECK +&_FILE_CHECK="symbian2.t32" +if os.file(&_FILE_CHECK) + ( + TASK.CONFIG symbian2 ; loads Symbian OS awareness (symbian2.t32) + MENU.ReProgram symbian2 ; loads Symbian OS menu (symbian2.men) + ) +else + ( + TASK.CONFIG c:\t32\demo\arm\kernel\symbian\eka2\symbian2 ; loads Symbian OS awareness (symbian2.t32) + MENU.ReProgram c:\t32\demo\arm\kernel\symbian\eka2\symbian2 ; loads Symbian OS menu (symbian2.men) + ) + +HELP.FILTER.Add rtossymbian2 ; add Symbian OS awareness manual to help filter +&_SYMBIAN_OS_AWARENESS_ENABLED=(0==0) + diff -r 000000000000 -r 5de814552237 navienginebsp/tools/testreference/lauterbach/writecurrentconfig.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebsp/tools/testreference/lauterbach/writecurrentconfig.cmm Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,43 @@ +// +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +////////////////////////////////////////////////////////////////////////////// +// Writes the current config to file +////////////////////////////////////////////////////////////////////////////// + + +// Open the config file for writing +open #1 currentconfig.cmm /Create + +// Write the config to the file in script format for loading later +write #1 "&"+"Platform="+'"'+"&Platform"+'"' +write #1 "&"+"AutoloadModule="+'"'+"&AutoloadModule"+'"' +write #1 "&"+"RamAddr="+'"'+"&RamAddr"+'"' +write #1 "&"+"RamImage="+'"'+"&RamImage"+'"' +write #1 "&"+"RamAddr1="+'"'+"&RamAddr1"+'"' +write #1 "&"+"RamImage1="+'"'+"&RamImage1"+'"' +write #1 "&"+"RamAddr2="+'"'+"&RamAddr2"+'"' +write #1 "&"+"RamImage2="+'"'+"&RamImage2"+'"' +write #1 "&"+"RamAddr3="+'"'+"&RamAddr3"+'"' +write #1 "&"+"RamImage3="+'"'+"&RamImage3"+'"' +write #1 "&"+"RamAddr4="+'"'+"&RamAddr4"+'"' +write #1 "&"+"RamImage4="+'"'+"&RamImage4"+'"' +write #1 "&"+"FlashAddr="+'"'+"&FlashAddr"+'"' +write #1 "&"+"FlashImage="+'"'+"&FlashImage"+'"' +write #1 "&"+"FlashWriteProtect="+'"'+"&FlashWriteProtect"+'"' +write #1 "&"+"FlashEraseProtect="+'"'+"&FlashEraseProtect"+'"' + +// All done, so close the file +close #1 \ No newline at end of file diff -r 000000000000 -r 5de814552237 navienginebspflexible/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebspflexible/bld.inf Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +PRJ_PLATFORMS +ARM4 ARMV5 +ARM4SMP ARMV5SMP + +#define FLEXIBLE +#include "../navienginebsp/ne1_tb/memmodel_bld.inf" diff -r 000000000000 -r 5de814552237 navienginebspflexible/variant.mmh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/navienginebspflexible/variant.mmh Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#undef VariantTarget +#define VariantTarget(name,ext) _fne1_tb_##name##.##ext +#include "../navienginebsp/ne1_tb/variant.mmh" +#undef MM_MULTIPLE +#define MM_FLEXIBLE +#define DEMAND_PAGING_EMULATION diff -r 000000000000 -r 5de814552237 package_definition.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/package_definition.xml Tue Sep 28 18:00:05 2010 +0100 @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + +