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)
--- /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
--- /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 <e32std.h>
+#include <e32std_private.h>
+#include <e32svr.h>
+#include <e32cons.h>
+#include <f32file.h>
+#include <hal.h>
+#include <u32hal.h>
+#include "flash_nor.h"
+#include <d32comm.h>
+
+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<KConfigBlockSize ; ++i, ++dest, ++j)
+ *dest=*j;
+ }
+ else
+ {
+ PrintToScreen(_L("Config area was blank, setting defaults\r\n"));
+
+ aConfigBlock.iMagic = KUidUBootldrCfgMagic;
+ aConfigBlock.iPortNumber = KUartPortNumber;
+ aConfigBlock.iBaudRate = EBps115200;
+ aConfigBlock.iLoadDevice = ELoadDrive;
+
+ // Write the new block to flash
+ WriteConfig();
+ }
+
+ // Configure bootloader from config block
+ SerialDownloadPort = aConfigBlock.iPortNumber;
+ SerialBaud = aConfigBlock.iBaudRate;
+ LoadDevice = (TLoadDevice)aConfigBlock.iLoadDevice;
+
+ // The H4 supports downloading images via the USB Mass Storage method. As
+ // the method of detecting a USB-MS boot is rather awkward the task is
+ // performed at a variant level.
+ if (LoadDevice==ELoadUSBMS)
+ {
+ // Read the custom restart reason from the hal
+ TInt aRestartReason;
+ TInt r = HAL::Get(HAL::ECustomRestartReason, aRestartReason);
+ if (r!=KErrNone)
+ {
+ PrintToScreen(_L("Failed to read restart reason from HAL (0x%x)"), r);
+ RDebug::Printf("Failed to read restart reason from HAL (0x%x)", r);
+ BOOT_FAULT();
+ }
+
+ // Decode the On H4 the restart reasons get shifted internally
+ if (aRestartReason & (KtRestartCustomRestartUSBLoader >> 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;
+ }
--- /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, <value>
+
+; 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, <multiplier>
+; INIT_NUMERIC_CONSTANT CFG_KernelHeapBaseSize, <base>
+;
+; The initial kernel heap size is MAX( <base> + <multiplier> * N / 16, value specified in ROMBUILD )
+; where N is the total physical RAM size in pages.
+; <base> defaults to 24K and <multiplier> 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
--- /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 <e32cmn.h>
+#include "naviengine.h"
+#include "flash_nor.h"
+#include <d32comm.h>
+
+#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
--- /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
--- /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__
+
--- /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 <e32cia.h>
+#include <naviengine_priv.h>
+#include <naviengine.h>
+#include "navienginecia.h"
+#include <upd35001_timer.h>
+
+
+__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);
+ }
+
+
--- /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 <naviengine_priv.h>
+#include <upd35001_timer.h>
+
+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);
+ }
+
--- /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 *)
+
--- /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)
+
--- /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<int> &, 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 *)
+
--- /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 <drivers/iic.h>
+#include <drivers/iic_channel.h>
+#include <assp/naviengine/naviengine_priv.h>
+#include <drivers/gpio.h>
+#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<KMaxName> 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;
+ }
+
--- /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 <assp/naviengine/naviengine.h>
+#include <drivers/gpio.h>
+#include <drivers/iic_channel.h>
+#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_
--- /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 <drivers/iic_transaction.h>
+#else
+#include <drivers/iic.h>
+#endif
+
+#include <drivers/iic_channel.h>
+#include <assp/naviengine/naviengine.h>
+#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
+
--- /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__*/
--- /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 <drivers/iic.h>
+#include <drivers/iic_channel.h>
+#include <assp/naviengine/naviengine_priv.h>
+#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;
+ }
+
--- /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 <assp/naviengine/naviengine.h>
+#include <drivers/iic.h>
+#include <drivers/iic_channel.h>
+#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__*/
--- /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
+
+
--- /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 <hcrconfig_csi.h>
+
+
+#endif // HCR_PSL_CONFIG_CSI_INC_INL
+
--- /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 <drivers/hcr.h>
+
+
+
+// -- 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
--- /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 <variant.mmh>
+#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
--- /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 <variant.mmh>
+#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
--- /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 <kernel/kern_priv.h>
+#include <assp.h>
+#include <naviengine_priv.h>
+#include <navienginedma.h>
+#include <dma.h>
+
+// 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<KDmaHWCtrl32Count;i++)
+ {
+ for (j=0;j<KDmaCtrl32HWSubChannelCount; j++) InitHWChannel(EDMACtrl32, i, j);
+ AsspRegister::Write32(KDMAC32Base+i*KDMAGroupOffset+KHoDMACONT, 0);
+ }
+ }
+
+//Initialises a single H/W channel
+void TNaviEngineDmac::InitHWChannel (ENaviEngineDmaController aNEController, TInt aGroup, TInt aSubChannel)
+ {
+ TUint neCtrlBase = 0;
+ switch(aNEController)
+ {
+ case EDMACtrl32: neCtrlBase = KDMAC32Base ; break;
+ default: __DMA_CANT_HAPPEN();
+ }
+ neCtrlBase += aGroup*KDMAGroupOffset + aSubChannel*KDMAChannelOffset;
+ AsspRegister::Write32(neCtrlBase+KHoDMACHS, KHtDMACHS_EN_EN); //disable channel
+ }
+
+#if defined(NE1_DMA_DOUBLE_BUFFER)
+
+#ifdef _DEBUG
+//These values indicate whether all corner cases are running.
+//Proper test shouldn't leave any of these values to zero.
+TInt InterruptCounter_DMA32 = 0; // Interrupt counter
+TInt Transfer_IdleOnStart = 0; // DMA channel is idle on the start of Transfer.
+TInt Transfer_NotIdleOnStart = 0; // DMA channel is not idle on the start of Transfer.
+TInt Transfer_MatchWorkSetTrue = 0; // Descriptor matches "work set" registers
+TInt Transfer_MatchWorkSetFalse = 0;// Descriptor doesn't match "work set" descriptor.
+#endif
+
+void TNaviEngineDmac::Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr)
+//
+// Initiates a (previously constructed) request on a specific channel.
+//
+ {
+ TDmaChannel& mutableChannel = const_cast<TDmaChannel&>(aChannel);
+ TNE1DmaChannel& channel = static_cast<TNE1DmaChannel&>(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<TDmaChannel&>(aChannel);
+ TNE1DmaChannel& channel = static_cast<TNE1DmaChannel&>(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<TDmaChannel&>(aChannel);
+ TNE1DmaChannel& channel = static_cast<TNE1DmaChannel&>(mutableChannel);
+
+ __KTRACE_OPT(KDMA, Kern::Printf(">TNaviEngineDmac::StopTransfer channel=%d", channel.PslId()));
+
+ channel.StopTransfer();
+
+ __KTRACE_OPT(KDMA, Kern::Printf("<TNaviEngineDmac::StopTransfer channel=%d", channel.PslId()));
+ }
+
+TBool TNaviEngineDmac::IsIdle(const TDmaChannel& aChannel)
+ {
+ TDmaChannel& mutableChannel = const_cast<TDmaChannel&>(aChannel);
+ TNE1DmaChannel& channel = static_cast<TNE1DmaChannel&>(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<TNaviEngineDmac*>(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<<channel.iTransferDataShift) * KMaxDMAUnitTransferLen;
+ }
+
+
+TUint TNaviEngineDmac::MemAlignMask(TDmaChannel& aChannel, TUint /*aFlags*/, TUint32 /*aPslInfo*/)
+//
+// Returns the memory buffer alignment restrictions mask for a given transfer.
+//
+ {
+ TNE1DmaChannel& channel = (TNE1DmaChannel&)aChannel;
+ return (1<<channel.iTransferDataShift) - 1;
+ }
+
+
+void TNaviEngineDmac::InitHwDes(const SDmaDesHdr& aHdr, TUint32 aSrc, TUint32 aDest, TInt aCount,
+ TUint aFlags, TUint32 /*aPslInfo*/, TUint32 /*aCookie*/)
+//
+// Sets up (from a passed in request) the descriptor with that fragment's source and destination address,
+// the fragment size, and the (driver/DMA controller) specific transfer parameters (mem/peripheral,
+// burst size, transfer width).
+//
+ {
+ TDmaDesc* pD = HdrToHwDes(aHdr);
+
+ __KTRACE_OPT(KDMA, Kern::Printf("TNaviEngineDmac::InitHwDes 0x%08X", pD));
+
+ // Unaligned descriptor? Bug in generic layer!
+ __DMA_ASSERTD(IsHwDesAligned(pD));
+
+ pD->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<TNaviEngineDmac*>(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<KDmaCtrl32HWSubChannelCount;i++)
+ {
+ TInt channel = DMAC32_HWChannelsLocator[aController][i];
+ #ifdef _DEBUG
+ if (channel >= 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<KDmaCtrl32HWSubChannelCount;i++)
+ {
+ TInt dchs= AsspRegister::Read32(KDMAC32Base+aController*KDMAGroupOffset+i*KDMAChannelOffset+KHoDMACHS);
+
+ if (dchs&KHtDMACHS_ERR)
+ {
+ TInt channel = DMAC32_HWChannelsLocator[aController][i];
+ #ifdef _DEBUG
+ if (channel >= 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<TDmaDesc*>(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<TUint32>(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<TNE1DmaChannel*>(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();
+ }
--- /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 <kernel/kern_priv.h>
+#include <assp.h>
+#include <naviengine_priv.h>
+#include <navienginedma.h>
+
+#include <dma.h>
+#include <dma_hai.h>
+
+
+// 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<KDmaHWCtrl32Count;i++)
+ {
+ for (j=0;j<KDmaCtrl32HWSubChannelCount; j++) InitHWChannel(EDMACtrl32, i, j);
+ AsspRegister::Write32(KDMAC32Base+i*KDMAGroupOffset+KHoDMACONT, 0);
+ }
+ }
+
+//Initialises a single H/W channel
+void TNaviEngineDmac::InitHWChannel (ENaviEngineDmaController aNEController, TInt aGroup, TInt aSubChannel)
+ {
+ TUint neCtrlBase = 0;
+ switch(aNEController)
+ {
+ case EDMACtrl32: neCtrlBase = KDMAC32Base ; break;
+ default: __DMA_CANT_HAPPEN();
+ }
+ neCtrlBase += aGroup*KDMAGroupOffset + aSubChannel*KDMAChannelOffset;
+ AsspRegister::Write32(neCtrlBase+KHoDMACHS, KHtDMACHS_EN_EN); //disable channel
+ }
+
+#if defined(NE1_DMA_DOUBLE_BUFFER)
+
+#ifdef _DEBUG
+//These values indicate whether all corner cases are running.
+//Proper test shouldn't leave any of these values to zero.
+TInt InterruptCounter_DMA32 = 0; // Interrupt counter
+TInt Transfer_IdleOnStart = 0; // DMA channel is idle on the start of Transfer.
+TInt Transfer_NotIdleOnStart = 0; // DMA channel is not idle on the start of Transfer.
+TInt Transfer_MatchWorkSetTrue = 0; // Descriptor matches "work set" registers
+TInt Transfer_MatchWorkSetFalse = 0;// Descriptor doesn't match "work set" descriptor.
+#endif
+
+void TNaviEngineDmac::Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr)
+//
+// Initiates a (previously constructed) request on a specific channel.
+//
+ {
+ TDmaChannel& mutableChannel = const_cast<TDmaChannel&>(aChannel);
+ TNE1DmaChannel& channel = static_cast<TNE1DmaChannel&>(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<TDmaChannel&>(aChannel);
+ TNE1DmaChannel& channel = static_cast<TNE1DmaChannel&>(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<TDmaChannel&>(aChannel);
+ TNE1DmaChannel& channel = static_cast<TNE1DmaChannel&>(mutableChannel);
+
+ __KTRACE_OPT(KDMA, Kern::Printf("TNaviEngineDmac::StopTransfer channel=%d", channel.PslId()));
+
+ channel.StopTransfer();
+
+ __KTRACE_OPT(KDMA, Kern::Printf("<TNaviEngineDmac::StopTransfer channel=%d", channel.PslId()));
+ }
+
+TBool TNaviEngineDmac::IsIdle(const TDmaChannel& aChannel)
+//
+// Returns the state of a given channel.
+//
+ {
+ TDmaChannel& mutableChannel = const_cast<TDmaChannel&>(aChannel);
+ TNE1DmaChannel& channel = static_cast<TNE1DmaChannel&>(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<TNaviEngineDmac*>(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<<channel.iTransferDataShift) * KMaxDMAUnitTransferLen;
+ }
+
+
+TUint TNaviEngineDmac::AddressAlignMask(TDmaChannel& aChannel, TUint /*aSrcFlags*/, TUint /*aDstFlags*/,
+ TUint32 /*aPslInfo*/)
+//
+// Returns the memory buffer alignment restrictions mask for a given transfer.
+//
+ {
+ TNE1DmaChannel& channel = (TNE1DmaChannel&)aChannel;
+ return (1<<channel.iTransferDataShift) - 1;
+ }
+
+
+TInt TNaviEngineDmac::InitHwDes(const SDmaDesHdr& aHdr, const TDmaTransferArgs& aTransferArgs)
+//
+// Sets up (from a passed in request) the descriptor with that fragment's
+// transfer parameters.
+//
+ {
+ TDmaDesc* pD = HdrToHwDes(aHdr);
+
+ __KTRACE_OPT(KDMA, Kern::Printf("TNaviEngineDmac::InitHwDes 0x%08X", pD));
+
+ // Unaligned descriptor? Bug in generic layer!
+ __DMA_ASSERTD(IsHwDesAligned(pD));
+
+ 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->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<TNaviEngineDmac*>(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<KDmaCtrl32HWSubChannelCount;i++)
+ {
+ TInt channel = DMAC32_HWChannelsLocator[aController][i];
+ #ifdef _DEBUG
+ if (channel >= 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<KDmaCtrl32HWSubChannelCount;i++)
+ {
+ TInt dchs= AsspRegister::Read32(KDMAC32Base+aController*KDMAGroupOffset+i*KDMAChannelOffset+KHoDMACHS);
+
+ if (dchs&KHtDMACHS_ERR)
+ {
+ TInt channel = DMAC32_HWChannelsLocator[aController][i];
+ #ifdef _DEBUG
+ if (channel >= 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<TDmaDesc*>(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<TUint32>(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<TNE1DmaChannel*>(aChannel);
+ channel->Close();
+ }
+ else if(aChannel->iController == &Controller64)
+ {
+ TNeSgChannel* channel = static_cast<TNeSgChannel*>(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<TDmaChannel&>(aChannel);
+ TNeSgChannel& channel = static_cast<TNeSgChannel&>(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<TDmaChannel&>(aChannel);
+ TNeSgChannel& channel = static_cast<TNeSgChannel&>(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<const TNeSgChannel&>(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<TLinAddr>(&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<TUint8>(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("<TNaviEngineDmac64Sg::AppendHwDes"));
+ }
+
+
+void TNaviEngineDmac64Sg::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.
+//
+ {
+ __KTRACE_OPT(KDMA, Kern::Printf("TNaviEngineDmac64Sg::UnlinkHwDes"));
+ TDma64Desc* pD = HdrToHwDes(aHdr);
+
+ //Descriptor is now an end link
+ pD->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<TNaviEngineDmac64Sg*>(aThis);
+
+ const TUint32 channelTcStates = AsspRegister::Read32(KHwDMAC64Base + Cmn::KHoTc);
+ const TUint32 channelErrStates = AsspRegister::Read32(KHwDMAC64Base + Cmn::KHoErr);
+
+ TNeSgChannel* channel = NULL;
+ for (TInt i=0; i<Dma64::KChannelCount; i++)
+ {
+ const TUint32 mask = (1<<i);
+ const TBool transferComplete = (channelTcStates & mask);
+ const TBool error = (channelErrStates & mask);
+
+
+ channel = me.iChannels + i;
+ const TInt irq = __SPIN_LOCK_IRQSAVE(channel->iLock);
+
+ 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<TDma64Desc*>(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();
+ }
--- /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
+
--- /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
+
--- /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
+
--- /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 <naviengine_priv.h>
+#include <gpio.h>
+
+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<TUint16>(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<GPIO::TGpioBaseId>((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<TInt>(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<<pinId) != (lastState & 1<<pinId))
+ {
+ // state has changed so reset count and lastState
+ lastState = AsspRegister::Read32(KHwRoGpio_Port_Value);
+ count = 0;
+ retries--;
+ }
+ }
+
+ if (retries == 0)
+ {
+ // too many retries
+ return KErrTimedOut;
+ }
+
+ aVal = state;
+ return KErrNone;
+ }
+
+EXPORT_C TInt GPIO::SetPinMode
+ (
+ TInt aId,
+ TGpioMode aMode
+ )
+ {
+ TUint16 pinId = DevicePinId(aId);
+ // the chip doesn't support modes, so just store it
+ if (pinId > 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<<pinId);
+ }
+ else
+ {
+ AsspRegister::Write32(KHwRwGpio_Port_Control_Enable, 1<<pinId);
+ }
+ return KErrNone;
+ }
+
+EXPORT_C TInt GPIO::GetPinDirection
+ (
+ TInt aId,
+ TGpioDirection & aDirection
+ )
+ {
+ TUint16 pinId = DevicePinId(aId);
+ if (pinId > KHwGpioPinMax)
+ {
+ return KErrArgument;
+ }
+ // port enabled means output, disabled means input
+ TUint enabled = AsspRegister::Read32(KHwRwGpio_Port_Control_Enable);
+ if (enabled & 1<<pinId)
+ {
+ aDirection = EOutput;
+ }
+ else
+ {
+ aDirection = EInput;
+ }
+ return KErrNone;
+ }
+
+EXPORT_C TInt GPIO::SetPinBias
+ (
+ TInt aId,
+ TGpioBias /*aBias*/
+ )
+ {
+ TUint16 pinId = DevicePinId(aId);
+ // pin bias not supported
+ if (pinId > 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<<pinId);
+ // enable interrupt
+ AsspRegister::Write32(KHwRwGpio_Int_Enable, 1<<pinId);
+ GpioUnlock(irq);
+ return KErrNone;
+ }
+
+EXPORT_C TInt GPIO::DisableInterrupt
+ (
+ 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;
+ }
+ // disable interrupt
+ AsspRegister::Write32(KHwWoGpio_Int_Disable, 1<<pinId);
+ // disable hold
+ TUint32 held = AsspRegister::Read32(KHwRwGpio_Int_Hold);
+ AsspRegister::Write32(KHwRwGpio_Int_Hold, held & !(1<<pinId));
+ GpioUnlock(irq);
+ return KErrNone;
+ }
+
+EXPORT_C TInt GPIO::IsInterruptEnabled
+ (
+ TInt aId,
+ TBool & aEnable
+ )
+ {
+ TUint16 pinId = DevicePinId(aId);
+ if (pinId > KHwGpioPinMax)
+ {
+ return KErrArgument;
+ }
+ TInt irq = GpioLock();
+ if (GpioPins[pinId].iIsr == NULL)
+ {
+ GpioUnlock(irq);
+ // nothing bound
+ return KErrGeneral;
+ }
+ aEnable = AsspRegister::Read32(KHwRwGpio_Int_Enable) & (1<<pinId);
+ GpioUnlock(irq);
+
+ return KErrNone;
+ }
+
+EXPORT_C TInt GPIO::ClearInterrupt
+ (
+ TInt aId
+ )
+ {
+ TUint16 pinId = DevicePinId(aId);
+ if (pinId > KHwGpioPinMax)
+ {
+ return KErrArgument;
+ }
+ // clear pin interrupt status
+ AsspRegister::Write32(KHwRwGpio_Int, 1<<pinId);
+ return KErrNone;
+ }
+
+EXPORT_C TInt GPIO::GetMaskedInterruptState
+ (
+ TInt aId,
+ TBool & aActive
+ )
+ {
+ TUint16 pinId = DevicePinId(aId);
+ if (pinId > KHwGpioPinMax)
+ {
+ return KErrArgument;
+ }
+ TInt irq = GpioLock();
+ aActive = AsspRegister::Read32(KHwRwGpio_Int_Enable) & AsspRegister::Read32(KHwRwGpio_Int) & (1<<pinId);
+ GpioUnlock(irq);
+ return KErrNone;
+ }
+
+EXPORT_C TInt GPIO::GetRawInterruptState
+ (
+ TInt aId,
+ TBool & aActive
+ )
+ {
+ TUint16 pinId = DevicePinId(aId);
+ if (pinId > KHwGpioPinMax)
+ {
+ return KErrArgument;
+ }
+ aActive = AsspRegister::Read32(KHwRwGpio_Int) & (1<<pinId);
+ return KErrNone;
+ }
+
+EXPORT_C TInt GPIO::SetInterruptTrigger
+ (
+ TInt aId,
+ TGpioDetectionTrigger aTrigger
+ )
+ {
+ TUint16 pinId = DevicePinId(aId);
+ if (pinId > 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<<pinId)) // reg will have 0 for input 1 for output
+ {
+ GpioUnlock(irq);
+ return KErrGeneral;
+ }
+ GpioUnlock(irq);
+ TUint32 state;
+ if (GpioPins[pinId].iDebounce == 0)
+ {
+ // just read it if we are not debouncing
+ state = AsspRegister::Read32(KHwRoGpio_Port_Value);
+ }
+ else
+ {
+ // work out debounced state
+ TInt err = GetDebouncedState(aId, state);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ }
+
+ if (state & (1<<pinId))
+ {
+ aState = EHigh;
+ }
+ else
+ {
+ aState = ELow;
+ }
+
+ return KErrNone;
+ }
+
+EXPORT_C TInt GPIO::SetOutputState
+ (
+ TInt aId,
+ TGpioState aState
+ )
+ {
+ TUint16 pinId = DevicePinId(aId);
+ if (pinId > 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<<pinId))
+ {
+ aState = EHigh;
+ }
+ else
+ {
+ aState = ELow;
+ }
+ return KErrNone;
+ }
+
+EXPORT_C TInt GPIO::GetInputState
+ (
+ TInt aId,
+ TGpioCallback * /*aCb*/
+ )
+ {
+ TUint16 pinId = DevicePinId(aId);
+ // asynch calls not supported
+ if (pinId > 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;
+ }
--- /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);
+ }
+
--- /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
+
+
--- /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 <assp/naviengine/naviengine.h>
+#include <assp/naviengine/navienginedma.h>
+
+#include <assp/naviengine/hcrconfig_assp.h>
+
+
+#endif // 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_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
+
+
--- /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 <drivers/hcr.h>
+
+
+
+// -- 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
--- /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
--- /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 <kernel/kernel.h>
+#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<iChannelsNum;i++) // TBD: for now, in future need to call into ConfRep to populate the array of interface Ids
+ chanArray[i]=i; // without ConfRep, interface Ids are just the channel numbers
+
+ DI2sChannelBase* chan=NULL;
+ for(TInt j=0;j<iChannelsNum;j++)
+ {
+ err=DI2sChannelBase::CreateChannels(chan,chanArray[j]); // this creates the channel corresponding to the interface Id passed and return it in chan
+ if(chan)
+ channels[j]=chan; // j is the channel number
+ else
+ {
+ err=KErrNotFound;
+ break;
+ }
+ }
+ if(err==KErrNone)
+ iChannels=channels;
+ Kern::Free(chanArray); // no longer need this
+ return err;
+ }
+
+/**,
+ Configures the interface.
+
+ @param aInterfaceId The interface Id.
+ @param aConfig A pointer to the configuration as one of TI2sConfigBufV01 or greater.
+
+ @return KErrNone, if successful;
+ KErrArgument, if aInterfaceId is invalid or aConfig is NULL;
+ KErrNotSupported, if the configuration is not supported by this interface;
+ KErrInUse, if interface is not quiescient (a transfer is under way).
+ */
+EXPORT_C TInt I2s::ConfigureInterface(TInt aInterfaceId, TDes8* aConfig)
+ {
+ TUint16 chanId=CHANNEL_ID_FROM_INTERFACE_ID(aInterfaceId);
+ if((chanId >= 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_<CONDITION> 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_<CONDITION> 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;
+ }
+
--- /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 <naviengine.h>
+
+#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<TI2sConfigV01> 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<<iInterfaceId)<<18);
+
+ // change the divide I2SCLK ctrl value for this channel..
+ AsspRegister::Modify32(KHwSystemCtrlBase+KHoSCUDivideI2SCLKCtrl, 0xf<<(iInterfaceId<<3), div<<(iInterfaceId<<3));
+
+ // update the KHwI2SControl register
+ AsspSetBits(KHwI2SControl(iInterfaceId), val, KHsI2SCtrl_FCKLKSEL, 4);
+
+ // after changing FSCLKSEL and FSMODE - clear MSK_I2Sx mask bit
+ AsspRegister::Modify32(KHwBaseSCU + KHoSCUClockMaskCtrl, (1<<iInterfaceId)<<18, 0);
+ __SPIN_UNLOCK_IRQRESTORE(I2sLock,irq);
+
+ return KErrNone;
+ }
+
+TInt D2sChannelNE1_TB::GetSamplingRate(TInt& aSamplingRate)
+ {
+ if (iConfig.iRole == I2s::ESlave)
+ {
+ return KErrNotSupported;
+ }
+
+ TUint32 val = (AsspRegister::Read32(KHwI2SControl(iInterfaceId))>>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<<iInterfaceId)<<18);
+
+ // update the register (3 bits at KHsI2SCtrl_FSMODE)
+ AsspSetBits(KHwI2SControl(iInterfaceId), val, KHsI2SCtrl_FSMODE, 3);
+
+ // after changing FSCLKSEL and FSMODE - clear MSK_I2Sx mask bit
+ AsspRegister::Modify32(KHwBaseSCU + KHoSCUClockMaskCtrl, (1<<iInterfaceId)<<18, 0);
+ __SPIN_UNLOCK_IRQRESTORE(I2sLock,irq);
+
+ return KErrNone;
+ }
+
+TInt D2sChannelNE1_TB::GetFrameFormat(TInt& aLeftFramePhaseLength, TInt& aRightFramePhaseLength)
+ {
+ TInt frameLength=0;
+ switch(AsspGetBits(KHwI2SControl(iInterfaceId), KHsI2SCtrl_FSMODE, 3))
+ {
+ case 0:
+ frameLength = I2s::EFrame32Bit;
+ break;
+
+ case 1:
+ frameLength = I2s::EFrame48Bit;
+ break;
+
+ case 2:
+ frameLength = I2s::EFrame64Bit;
+ break;
+
+ case 3:
+ frameLength = I2s::EFrame128Bit;
+ break;
+
+ default:
+ return KErrGeneral; //unexpected value??
+ };
+
+ aLeftFramePhaseLength=aRightFramePhaseLength=frameLength/2; // on NaviEngine frames are symmetrical
+
+ return KErrNone;
+ }
+
+TInt D2sChannelNE1_TB::SetSampleLength(TInt /*aFramePhase*/, TInt aSampleLength)
+ {
+ if (AsspIsBitSet(KHwI2SControl(iInterfaceId), KHtI2SCtrl_TEN | KHtI2SCtrl_REN))
+ {
+ return KErrInUse;
+ }
+
+ TUint32 val=0;
+
+ switch(aSampleLength)
+ {
+ case I2s::ESample8Bit:
+ val = 0x8;
+ break;
+
+ case I2s::ESample16Bit:
+ val = 0x10;
+ break;
+
+ case I2s::ESample24Bit:
+ val = 0x18;
+ break;
+
+ case I2s::ESample12Bit:
+ case I2s::ESample32Bit:
+ return KErrNotSupported;
+ }
+
+ // update the register..
+ AsspSetBits(KHwI2SControl(iInterfaceId), val, KHsI2SCtrl_DLENGTH,5); // [4:0] sampling data length);
+
+ return KErrNone;
+ }
+
+TInt D2sChannelNE1_TB::GetSampleLength(TInt /*aFramePhase*/, TInt& aSampleLength)
+ {
+ // sample length can't be configured separately for left/right channels..
+ // .. in this chip, so aFramePhase is ignored
+
+ TUint32 val=AsspRegister::Read32(KHwI2SControl(iInterfaceId)) & 0x1F;
+
+ switch(val)
+ {
+ case 0x8:
+ aSampleLength = I2s::ESample8Bit;
+ break;
+
+ case 0x10:
+ aSampleLength = I2s::ESample16Bit;
+ break;
+
+ case 0x18:
+ aSampleLength = I2s::ESample24Bit;
+ break;
+ }
+
+ return KErrNone;
+ }
+
+TInt D2sChannelNE1_TB::SetDelayCycles(TInt aFramePhase, TInt aDelayCycles)
+ {
+ return KErrNotSupported;
+ }
+
+TInt D2sChannelNE1_TB::GetDelayCycles(TInt aFramePhase, TInt& aDelayCycles)
+ {
+ return KErrNotSupported;
+ }
+
+TInt D2sChannelNE1_TB::ReadReceiveRegister(TInt aFramePhase, TInt& aData)
+ {
+ // should check here, if sample length was configured,
+ // but once the interface is properly configured, this check would add unnecessary overhead.
+
+ // since there is only one fifo for both channels in this chip,
+ // we need to read Left and then Right channel data in sequence.
+
+ TInt oldFP=__e32_atomic_swp_ord32(&iLastPhaseInReadFifo,aFramePhase); // atomic as this may be used in ISR too
+ if(aFramePhase == oldFP)
+ {
+ return KErrNotSupported;
+ }
+
+ // and get the current data from the fifo register
+ aData = AsspRegister::Read32(KHwI2SDataIn(iInterfaceId));
+ return KErrNone;
+ }
+
+TInt D2sChannelNE1_TB::WriteTransmitRegister(TInt aFramePhase, TInt aData)
+ {
+ // should check here, if sample length was configured,
+ // but once the interface is properly configured, this check would add unnecessary overhead.
+
+ // since there is only one fifo for both channels in this chip,
+ // we need to write Left and then right channel data in sequence.
+
+ TInt oldFP=__e32_atomic_swp_ord32(&iLastPhaseInWriteFifo,aFramePhase); // atomic as this may be used in ISR too
+ if(aFramePhase == oldFP)
+ {
+ return KErrNotSupported;
+ }
+
+ // and update the fifo register
+ AsspRegister::Write32(KHwI2SDataOut(iInterfaceId), aData);
+
+ return KErrNone;
+ }
+
+TInt D2sChannelNE1_TB::ReadTransmitRegister(TInt aFramePhase, TInt& aData)
+ {
+ // since there is only one fifo for both channels in this chip,
+ // we can only read the data for the last written phase (either left or right)
+
+ TInt curFp=__e32_atomic_load_acq32(&iLastPhaseInWriteFifo);
+ if(aFramePhase != curFp)
+ {
+ return KErrArgument;
+ }
+
+ // read the register
+ aData = AsspRegister::Read32(KHwI2SDataOut(iInterfaceId));
+
+ return KErrNone;
+ }
+
+TInt D2sChannelNE1_TB::ReadRegisterModeStatus(TInt aFramePhase, TInt& aFlags)
+ {
+ return KErrNotSupported; // register PIO mode not supported (FIFO always present)
+ }
+
+TInt D2sChannelNE1_TB::EnableRegisterInterrupts(TInt aFramePhase, TInt aInterrupt)
+ {
+ return KErrNotSupported; // register PIO mode not supported (FIFO always present)
+ }
+
+TInt D2sChannelNE1_TB::DisableRegisterInterrupts(TInt aFramePhase, TInt aInterrupt)
+ {
+ return KErrNotSupported; // register PIO mode not supported (FIFO always present)
+ }
+
+TInt D2sChannelNE1_TB::IsRegisterInterruptEnabled(TInt aFramePhase, TInt& aEnabled)
+ {
+ return KErrNotSupported; // register PIO mode not supported (FIFO always present)
+ }
+
+TInt D2sChannelNE1_TB::EnableFIFO(TInt /*aFramePhase*/, TInt aFifoMask)
+ {
+ TInt val=0;
+
+ // Set and clear fifo init bits for transmit/receive
+ // tere are only two FIFOs - not separated to phases..
+ if(aFifoMask & I2s::ETx)
+ val = KHtI2SFifoCtrl_TFIFOCLR;
+
+ if(aFifoMask & I2s::ERx)
+ val |= KHtI2SFifoCtrl_RFIFOCLR;
+
+ AsspRegister::Modify32(KHwI2SFifoControl(iInterfaceId), 0, val);
+ AsspRegister::Modify32(KHwI2SFifoControl(iInterfaceId), val, 0);
+
+ return KErrNone;
+ }
+
+TInt D2sChannelNE1_TB::DisableFIFO(TInt aFramePhase, TInt aFifoMask)
+ {
+ // fifo is always enabled in this chip..
+ return KErrNotSupported;
+ }
+
+TInt D2sChannelNE1_TB::IsFIFOEnabled(TInt /*aFramePhase*/, TInt& aEnabled)
+ {
+ // fifo is always enabled in this chip..
+ aEnabled = I2s::ERx|I2s::ETx;
+ return KErrNone;
+ }
+
+TInt D2sChannelNE1_TB::SetFIFOThreshold(TInt aFramePhase, TInt aDirection, TInt aThreshold)
+ {
+ // supported threshold values for this chip:
+ // 011b - 16-word space available
+ // 010b - 8-word space available
+ // 001b - 4-word space available
+ // 000b - 2-word space available
+ if (aThreshold < 0)
+ {
+ return KErrNotSupported;
+ }
+
+ // Determine, what value was specified, and adjust it down to one
+ // of the possible values
+ TInt i=15;
+ while(i>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;
+ }
+
+
--- /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 <naviengine_priv.h>
+
+#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
+ }
--- /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 <naviengine_priv.h>
+
+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 <arm_gic.h>
+
+#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("<Interrupt_Init1()"));
+ }
+
+//extern "C" void Interrupt_Init2AP()
+// {
+// }
+
+void NaviEngineInterrupt::Init3()
+ {
+ //
+ // Any further initialisation of the Hardware Interrupt Controller
+ // Note This is not called at the moment. Should be deleted.
+ }
+
+EXPORT_C TInt Interrupt::Bind(TInt aId, TIsr aIsr, TAny* aPtr)
+ {
+ __KTRACE_OPT(KEXTENSION,Kern::Printf("Interrupt::Bind id=%d func=%08x ptr=%08x", aId, aIsr, aPtr));
+ TUint id = (TUint)aId;
+ if (id<32 || id>=(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<KNumNaviEngineInts; i++)
+ {
+ Handlers[i].iPtr=(TAny*)i;
+ Handlers[i].iIsr=Spurious;
+ }
+ DisableAndClearAll();
+ Arm::SetIrqHandler((TLinAddr)NaviEngineInterrupt::IrqDispatch);
+ Arm::SetFiqHandler((TLinAddr)NaviEngineInterrupt::FiqDispatch);
+
+ // All interrupts are N-N (LSB = 1)
+ // Both edge (MSB = 1) and level triggered (MSB = 0)
+ // are present
+ for (TInt i=0; i<KNumNaviEngineInts; ++i)
+ {
+ TUint8 isEdge = 0x0;
+ if(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
--- /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 <variant.mmh>
+#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
--- /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 <videodriver.h>
+#include "platform.h"
+#include <nkern.h>
+#include <kernel/kernel.h>
+#include <kernel/kern_priv.h>
+#include <kernel/kpower.h>
+#include <naviengine_priv.h>
+#include "lcdgce.h"
+#include <naviengine_lcd.h>
+#include "powerresources.h"
+#include <resourcecontrol.h>
+
+// 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<yres/KGranularity; ++yb)
+ {
+ for (xb=0; xb<xres/KGranularity; ++xb)
+ {
+ TUint c=((xb*xb+yb*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; l<KGranularity; ++l, baddr+=bpl)
+ {
+ TUint32* p=(TUint32*)baddr;
+ if (bpp==8)
+ *p++=c8;
+ else if (bpp==16)
+ *p++=c16, *p++=c16;
+ else
+ {
+ *p++=c32+0x0;
+ *p++=c32+0x4;
+ *p++=c32+0x8;
+ *p++=c32+0xc;
+ c32+=0x100;
+ }
+ }
+ }
+ }
+
+ // Secure screen
+ TUint8* linePtr = (TUint8*)iSecureVideoInfo.iVideoAddress+
+ iSecureVideoInfo.iOffsetToFirstPixel;
+ TInt pixelSize = iSecureVideoInfo.iBitsPerPixel;
+ if(pixelSize>8)
+ pixelSize = (pixelSize+7)&~7; // Round up to whole number of bytes
+ TInt bytesPerLine = (pixelSize*iSecureVideoInfo.iSizeInPixels.iWidth) >> 3;
+ for(TInt y=0; y<iSecureVideoInfo.iSizeInPixels.iHeight; y++)
+ {
+ for(TInt x=0; x<bytesPerLine; x++)
+ linePtr[x] = x+y;
+ linePtr += iSecureVideoInfo.iOffsetBetweenLines;
+ }
+ }
+
+
+
+/**
+Get the size of the pallete
+
+@return the number of pallete entries
+*/
+TInt DLcdPowerHandler::NumberOfPaletteEntries()
+ {
+ TInt num = iVideoInfo.iIsPalettized ? 1<<iVideoInfo.iBitsPerPixel : 0;
+
+ __KTRACE_OPT(KEXTENSION,Kern::Printf("NumberOfPaletteEntries = %d", num));
+
+ return num;
+ }
+
+
+/**
+Retrieve the palette entry at a particular offset
+
+@param aEntry the palette index
+@param aColor a caller-supplied pointer to a location where the returned RGB color is to be stored
+@return KErrNone if successful
+ KErrNotSupported if the current vide mode does not support a palette
+ KErrArgument if aEntry is out of range
+*/
+TInt DLcdPowerHandler::GetPaletteEntry(TInt aEntry, TInt* aColor)
+ {
+ NKern::FMWait(&iLock);
+ if (!iVideoInfo.iIsPalettized)
+ {
+ NKern::FMSignal(&iLock);
+ return KErrNotSupported;
+ }
+
+ if ((aEntry < 0) || (aEntry >= 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<TScreenInfoV01> 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()<ELow)
+ r=KErrBadPower;
+ else
+ SetBacklightState(TBool(a1));
+ break;
+
+ case EDisplayHalBacklightOn:
+ kumemput32(a1,&iBacklightOn,sizeof(TInt));
+ break;
+
+ case EDisplayHalModeCount:
+ {
+ TInt ndm = SCREEN_UNIT_COUNT;
+ kumemput32(a1, &ndm, sizeof(ndm));
+ break;
+ }
+
+ case EDisplayHalSetMode:
+ if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetMode")))
+ return KErrPermissionDenied;
+ r = SetDisplayMode((TInt)a1);
+ break;
+
+ case EDisplayHalMode:
+ kumemput32(a1, &iVideoInfo.iDisplayMode, sizeof(iVideoInfo.iDisplayMode));
+ break;
+
+ case EDisplayHalSetPaletteEntry:
+ if(!Kern::CurrentThreadHasCapability(ECapabilityMultimediaDD,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetPaletteEntry")))
+ return KErrPermissionDenied;
+ r = SetPaletteEntry((TInt)a1, (TInt)a2);
+ break;
+
+ case EDisplayHalPaletteEntry:
+ {
+ TInt entry;
+ kumemget32(&entry, a1, sizeof(TInt));
+ TInt x;
+ r = GetPaletteEntry(entry, &x);
+ if (r == KErrNone)
+ kumemput32(a2, &x, sizeof(x));
+ break;
+ }
+
+ case EDisplayHalSetState:
+ {
+ if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetState")))
+ return KErrPermissionDenied;
+ if ((TBool)a1)
+ {
+ WsSwitchOnScreen();
+ }
+ else
+ {
+ WsSwitchOffScreen();
+ }
+ break;
+ }
+
+ case EDisplayHalState:
+ kumemput32(a1, &iDisplayOn, sizeof(TBool));
+ break;
+
+ case EDisplayHalColors:
+ {
+ TInt mdc = KConfigLcdMaxDisplayColors;
+ kumemput32(a1, &mdc, sizeof(mdc));
+ break;
+ }
+
+ case EDisplayHalCurrentModeInfo:
+ {
+ TPckgBuf<TVideoInfoV01> vPckg;
+ r = GetCurrentDisplayModeInfo(vPckg(), (TBool)a2);
+ if (KErrNone == r)
+ Kern::InfoCopy(*(TDes8*)a1,vPckg);
+ }
+ break;
+
+ case EDisplayHalSpecifiedModeInfo:
+ {
+ TPckgBuf<TVideoInfoV01> 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;
+ }
+
--- /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 <display.h>
+
+
+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__
--- /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 <e32cmn.h>
+#include <e32def.h>
+#include <naviengine_priv.h>
+#include <i2s.h>
+
+
+//
+// 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)
+ };
+
--- /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 <e32const.h>
+#include <e32hal.h>
+
+//-------------------------------------------------------------------
+// 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
--- /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
--- /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 <e32cia.h>
+#include <naviengine_priv.h>
+
+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);
+ }
--- /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 <naviengine_priv.h>
+#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
+ }
+
+
+
--- /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 <e32const.h>
+#include <platform.h>
+#include <e32hal.h>
+#include <assp.h>
+#include <kernel/kern_priv.h>
+
+
+
+// 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__
--- /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__
--- /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 <e32const.h>
+#include <arm.h>
+#include <assp.h>
+#include <assp/naviengine/naviengine.h>
+
+
+//----------------------------------------------------------------------------
+// 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
--- /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
--- /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 <drivers/dma.h>
+#include <assp/naviengine/naviengine.h>
+
+#include <platform.h>
+
+
+#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__
--- /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 <naviengine.h> // /assp/naviengine/
+#include <naviengine_priv.h> // /assp/naviengine/
+
+#include <drivers/usbc.h> // /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<TEndpoint*>(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<NaviEngineAssp*>(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<TUint8*>(reinterpret_cast<const TUint8*>(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<TUint8*>(reinterpret_cast<const TUint8*>(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<TUint8*>(reinterpret_cast<const TUint8*>(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<TUint8*>(reinterpret_cast<const TUint8*>(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<TNaviEngineAsspUsbcc*>(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<TNaviEngineAsspUsbcc*>(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 --------------------------------------------------------------------
--- /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__
--- /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 <kernel/kern_priv.h>
+
+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; i<count; ++i)
+ {
+ const TRange& r(iRangeList[i]);
+ __KTRACE_OPT(KPCI, Kern::Printf(" index:%d, start:%x, length:%x, end:%x, allocated:%d",
+ i, r.iStart, r.iLength, r.End(), r.iAllocated));
+ }
+ }
+
+TBool TAddressAllocator::InvariantCheck()
+ {
+ //Print();
+ const TInt count = iRangeList.Count();
+ __NK_ASSERT_ALWAYS(count>0);
+ __NK_ASSERT_ALWAYS(iRangeList[0].iStart==0);
+ __NK_ASSERT_ALWAYS(iRangeList[count-1].End()==iMaxSize-1);
+
+ for(TInt i=1; i<count; ++i)
+ {
+ const TRange& prev = iRangeList[i-1];
+ const TRange& curr = iRangeList[i];
+ __NK_ASSERT_ALWAYS(prev.End()==curr.iStart-1);
+ __NK_ASSERT_ALWAYS(curr.iLength>0);
+
+ //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<TRange> 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());
+ }
+
--- /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 <e32cmn.h>
+
+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<TRange> iRangeList; //a list of contiguous, non-overlapping address regions.
+ DMutex* iMutex;
+ };
+
+#endif //ALLOCATOR_H
--- /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 <naviengine.h>
+#include <kernel/kern_priv.h>
+
+//
+// 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>(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<DObject*&>(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>(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;
+ }
+
+
--- /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 <e32cmn.h>
+
+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<TChunkRecord> iChunks;
+ RArray<TSCRecord> iSharedChunks;
+ DMutex* iMutex;
+
+
+ };
+#endif // __CHUNKMAN_H__
--- /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 <naviengine.h>
+#include <naviengine_priv.h>
+
+//
+// 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; i<iNumOfBars; ++i)
+ {
+ r = iMappings.Append(emptyRecord);
+ __NK_ASSERT_ALWAYS(r==KErrNone);
+ }
+ }
+
+TMappingManager::~TMappingManager()
+ {
+ iMutex->Close(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)
+ aSize=KMinOutboundWindow;
+ else
+ aSize=Clp2(aSize); //round up to next Power of 2.
+
+ __NK_ASSERT_ALWAYS(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>(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<<aBarIndex));
+ //__KTRACE_OPT(KPCI, Kern::Printf("New bar enable register: 0x%08x", AsspRegister::Read32(iBaseAddress+KHoBarEnable)));
+
+ TMapping& newMapping = iMappings[aBarIndex];
+ newMapping.iPciAddr=aPciAddress;
+ newMapping.iPhysAddr=aPhysicalAddress;
+ newMapping.iSize=aSize;
+ newMapping.iUsed=ETrue;
+ }
+
+TInt TMappingManager::RemoveMapping(TUint32 aPhysicalAddress)
+ {
+ NKern::ThreadEnterCS();
+ Kern::MutexWait(*iMutex);
+
+ TInt r=KErrNone;
+ TInt barIndex=iMappings.Find(aPhysicalAddress, TMapping::PhysAddrCompare);
+
+ if(KErrNotFound==barIndex)
+ {
+ r=barIndex;
+ }
+ else
+ {
+ //clear the bits in the BarMask field of the ACR to invalidate access to Bar.
+ AsspRegister::Modify32(iBaseAddress+KHoAcr[barIndex], KHmAcr_BarMask, NULL);
+
+ //clear bit for this bar in the bar enable register
+ AsspRegister::Modify32(iBaseAddress+KHoBarEnable, (1<<barIndex), NULL);
+
+ TMapping& oldMapping = iMappings[barIndex];
+ r = iAllocator.DeAllocate(oldMapping.iPciAddr);
+ __NK_ASSERT_ALWAYS(KErrNone==r);
+
+ oldMapping.iUsed=EFalse;
+ }
+
+ Kern::MutexSignal(*iMutex);
+ NKern::ThreadLeaveCS();
+ return r;
+ }
+
+TInt TMappingManager::GetPciAddress(TUint32 aPhysicalAddress, TUint32& aPciAddress)
+ {
+ NKern::ThreadEnterCS();
+ Kern::MutexWait(*iMutex);
+
+ const TInt barIndex=iMappings.Find(aPhysicalAddress, TMapping::ContainsPhysical);
+ TInt r= KErrNotFound;
+
+ if(barIndex==KErrNotFound)
+ r = KErrNotFound;
+ else
+ {
+ aPciAddress=iMappings[barIndex].PciAddress(aPhysicalAddress);
+ r = KErrNone;
+ }
+
+ Kern::MutexSignal(*iMutex);
+ NKern::ThreadLeaveCS();
+ return r;
+ }
+
+TInt TMappingManager::GetPhysicalAddress(TUint32 aPciAddress, TUint32& aPhysicalAddress)
+ {
+ NKern::ThreadEnterCS();
+ Kern::MutexWait(*iMutex);
+
+ const TInt barIndex=iMappings.Find(aPciAddress, TMapping::ContainsPci);
+ TInt r= KErrNotFound;
+
+ if(barIndex==KErrNotFound)
+ r = KErrNotFound;
+ else
+ {
+ aPhysicalAddress=iMappings[barIndex].PhysAddress(aPciAddress);
+ r = KErrNone;
+ }
+
+ Kern::MutexSignal(*iMutex);
+ NKern::ThreadLeaveCS();
+ return r;
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/navienginebsp/naviengine_assp/pci/mapman.h 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:
+*
+*/
+
+
+
+#ifndef __MAPMAN_H__
+#define __MAPMAN_H__
+
+#include <e32cmn.h>
+
+//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<TMapping> iMappings;
+ DMutex* iMutex;
+ };
+#endif // __MAPMAN_H__
--- /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 <naviengine_priv.h>
+#include <naviengine.h>
+
+
+_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; i<KPciNumberOfBars; ++i)
+ {
+ const TInt barOffset=KPciBar0+(4*i);
+ const TUint32 size= ProbeBar(configSpace, barOffset);
+
+ if(NULL==size)
+ continue;
+
+ //allocate pci address range
+ TUint32 pciAddress=0;
+ r=iAllocator.Allocate(pciAddress, size);
+ if(r!=KErrNone)
+ break;
+
+ //tell the function what its address is.
+ r = func->AddMemorySpace(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<<KHsBus);
+ const TUint32 device=(aDevice<<KHsDevice);
+ const TUint32 function=(aFunction<<KHsFunction);
+ const TUint32 offset=(aDwordOffset<<KHsOffset);
+
+ __NK_ASSERT_DEBUG( (bus & (~KHmBus)) == NULL);
+ __NK_ASSERT_DEBUG( (device & (~KHmDevice)) == NULL);
+ __NK_ASSERT_DEBUG( (function & (~KHmFunction)) == NULL);
+ __NK_ASSERT_DEBUG( (offset & (~KHmOffset)) == NULL);
+
+ return (KHtCnfigEnable|
+ (bus & KHmBus)|
+ (device & KHmDevice)|
+ (function & KHmFunction)|
+ (offset & KHmOffset)
+ );
+ }
+
+/**
+Probes the specified bar to see whether it is implemented, if so
+then return the amount of memory space required.
+
+@note Driver does not currently support devices which request IO-space
+or 64-bit bars.
+*/
+TUint DNaviEnginePciBridge::ProbeBar(TAddrSpace& aCs, TUint32 aBarOffset)
+ {
+ __KTRACE_OPT(KPCI, Kern::Printf("DNaviEnginePciBridge::ProbeBar Probing BAR at Offset %d", aBarOffset));
+
+ //ignore any writable bits in positions [0:2]
+ //they shouldn't be writable but are for the NaviEngine host
+ //bridge
+ const TUint32 KHmIgnore= Bar::KHtMemSpaceType|Bar::KHmType|Bar::KHtPreFetchable;
+
+ aCs.Write32(aBarOffset, 0x00000000);
+ TUint32 initial= aCs.Read32(aBarOffset);
+ aCs.Write32(aBarOffset, KMaxTUint32);
+ TUint32 bar = aCs.Read32(aBarOffset);
+
+ //reset after probing
+ aCs.Write32(aBarOffset, 0x00000000);
+
+ if( (bar&(~KHmIgnore)) == (initial&(~KHmIgnore)) )
+ {
+ __KTRACE_OPT(KPCI, Kern::Printf(" Function doesn't implement BAR"));
+ return NULL;
+ }
+ if(bar & Bar::KHtMemSpaceType)
+ {
+ __KTRACE_OPT(KPCI, Kern::Printf(" IOSpace is not supported") );
+ return NULL;
+ }
+
+ if(bar & Bar::KHmType )
+ {
+ __KTRACE_OPT(KPCI, Kern::Printf(" Only support 32 bit address space") );
+ return NULL;
+ }
+
+ TUint size= (bar<<1)^(bar);
+ __KTRACE_OPT(KPCI, Kern::Printf(" Address space: %08x bytes", size));
+ return size;
+ }
+
+
+
+TUint8 DNaviEnginePciBridge::ReadConfig8(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 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<<Initiator::KHsA2PCAMask)| //modify incomming AHB address above 8k
+ (0x3<<Initiator::KHsType)| //incomming accesses will perform memory read/memory write
+ 0x1; //enable incomming address conversion
+ AsspRegister::Write32(iBaseAddr+Initiator::KHoReg1, window1Register);
+
+ AsspRegister::Write32(iBaseAddr+KHoBarEnable, 0); //disable all BARs, don't yet want access from PCI to AHB
+
+ AsspRegister::Modify32(iBaseAddr+KHoPciCtrlH ,NULL,
+ KHtPciCtrlH_Aerse|
+ KHtPciCtrlH_Dtimse|
+ KHtPciCtrlH_Perse|
+ KHtPciCtrlH_Rtyse|
+ KHtPciCtrlH_Tase
+ );
+ //report errors from PCI bus to AHB64PCI_ERR pin
+ //report errror on AHB to AHB64PCI_ERR pin
+ AsspRegister::Modify32(iBaseAddr+KHoError1, NULL,
+ KHtError1_PEEn|
+ KHtError1_AMEn
+ );
+
+ }
+
+void DNaviEnginePciBridge::ClearRegisters()
+ {
+ ClearErrors();
+
+ AsspRegister::Modify16(iBaseAddr+KHoPciCmd,
+ KHtPcicmd_Bmasen|
+ KHtPcicmd_Memen|
+ KHtPcicmd_Peren|
+ KHtPcicmd_Seren,
+ NULL);
+
+ AsspRegister::Modify32(iBaseAddr+KHoPciCtrlH ,
+ KHtPciCtrlH_CnfigDone|
+ KHtPciCtrlH_Aerse|
+ KHtPciCtrlH_Dtimse|
+ KHtPciCtrlH_Perse|
+ KHtPciCtrlH_Rtyse|
+ KHtPciCtrlH_Mase|
+ KHtPciCtrlH_Tase,
+ NULL
+ );
+
+ AsspRegister::Modify32(iBaseAddr+KHoError1,
+ KHtError1_PEEn|
+ KHtError1_AMEn,
+ NULL
+ );
+
+ AsspRegister::Write32(KHoCnfig_addr+iBaseAddr, 0x0);
+
+ AsspRegister::Write32(iBaseAddr+Initiator::KHoReg1, 0x0);
+ AsspRegister::Write32(iBaseAddr+Initiator::KHoReg2, 0x0);
+ }
+
+//Clear latched bits by wriring 1 to them
+void DNaviEnginePciBridge::ClearErrors()
+ {
+ AsspRegister::Modify16(iBaseAddr+KHoPciStatus, NULL,
+ KHtPciStatus_ParityError|
+ KHtPciStatus_SystemError|
+ KHtPciStatus_MasterAbrtRcvd|
+ KHtPciStatus_TargetAbrtRcvd|
+ KHtPciStatus_DPErrorAsserted
+ );
+
+ AsspRegister::Modify32(iBaseAddr+KHoError1, NULL,
+ KHtError1_SystemError|
+ KHtError1_AMEr
+ );
+
+ AsspRegister::Modify32(iBaseAddr+KHoPciCtrlH, NULL,
+ KHtPciCtrlH_Aper|
+ KHtPciCtrlH_Dtep|
+ KHtPciCtrlH_Dper|
+ KHtPciCtrlH_Rlex|
+ KHtPciCtrlH_Mabo|
+ KHtPciCtrlH_Tabo
+ );
+
+ }
+
+
+TInt DNaviEnginePciBridge::SetupInterrupts()
+ {
+ __KTRACE_OPT(KPCI, Kern::Printf("DNaviEnginePciBridge: SetupInterrupts()"));
+ TInt r = KErrNone;
+
+ __KTRACE_OPT(KPCI, Kern::Printf(" Binding EIntPciPErrB"));
+ r = Interrupt::Bind(EIntPciPErrB, ParityErrorISR, this);
+ __KTRACE_OPT(KPCI, Kern::Printf(" r=%d", r));
+
+ __KTRACE_OPT(KPCI, Kern::Printf(" Binding EIntPciSErrB"));
+ r = Interrupt::Bind(EIntPciSErrB, SystemErrorISR, this);
+ __KTRACE_OPT(KPCI, Kern::Printf(" r=%d", r));
+
+ __KTRACE_OPT(KPCI, Kern::Printf(" Binding EIntPciInt"));
+ r = Interrupt::Bind(EIntPciInt, PciISR, this);
+ __KTRACE_OPT(KPCI, Kern::Printf(" r=%d", r));
+
+ __KTRACE_OPT(KPCI, Kern::Printf(" Enabling EIntPciPErrB"));
+ r = Interrupt::Enable(EIntPciPErrB);
+ __KTRACE_OPT(KPCI, Kern::Printf(" r=%d", r));
+
+ __KTRACE_OPT(KPCI, Kern::Printf(" Enabling EIntPciSErrB"));
+ r = Interrupt::Enable(EIntPciSErrB);
+ __KTRACE_OPT(KPCI, Kern::Printf(" r=%d", r));
+
+ __KTRACE_OPT(KPCI, Kern::Printf(" Enabling EIntPciInt"));
+ Interrupt::Clear(EIntPciInt);
+ //r = Interrupt::Enable(EIntPciInt);
+ __KTRACE_OPT(KPCI, Kern::Printf(" r=%d", r));
+ return r;
+ }
+
+void DNaviEnginePciBridge::ParityErrorISR(void* aP)
+ {
+ Interrupt::Clear(EIntPciPErrB);
+ Kern::Fault("PCI Parity error",0);
+ }
+
+void DNaviEnginePciBridge::SystemErrorISR(void* aP)
+ {
+ Interrupt::Clear(EIntPciSErrB);
+ Kern::Fault("PCI System error",0);
+ }
+
+/**
+This interrupt is raised when a bus error has occured, if the
+appropriate bit has been set (KHtPciCtrlH_Mase).
+It will also be raised if a peripheral uses one of the
+native PCI interrupt lines - but this not yet supported.
+*/
+void DNaviEnginePciBridge::PciISR(void* aP)
+ {
+ Interrupt::Clear(EIntPciInt);
+ DNaviEnginePciBridge* bridge = static_cast<DNaviEnginePciBridge*>(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;
+ }
+
+
+
+
+
--- /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 <pci.h>
+#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
--- /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 <variant.mmh>
+#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
--- /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 <pci.h>
+#include <naviengine.h>
+#include <naviengine_priv.h>
+
+#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<DPciBridge> 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<TInt>& aListOfFunctions, TPciVendorId aVid, TDeviceId aDid)
+ {
+ if(aListOfFunctions.Count()>0)
+ return KErrArgument;
+
+ const TInt functionCount=iFunctions.Count();
+ TInt r=KErrNotFound;
+ for(TInt i=0; i<functionCount;++i)
+ {
+ TPciFunction* func=iFunctions[i];
+ if(func->VendorId()==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<TPciFunction> 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; bridge<numberOfPciBridges; ++bridge)
+ {
+ for(TInt bus=0; bus<KPciMaxBusses; ++bus)
+ {
+ for(TInt device=0; device<KPciMaxDevices; ++device)
+ {
+ for(TInt function=0; function<KPciMaxFunctions; ++function)
+ {
+ TPciFunction* func = iPciBridges[bridge]->Function(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; i<KPciNumberOfBars;++i)
+ {
+ TInt r=iMemorySpaces.Append(NULL);
+ __NK_ASSERT_ALWAYS(KErrNone==r);
+ }
+
+ iConfigSpace = new TConfigSpace(*this, iBridge);
+ __NK_ASSERT_ALWAYS(iConfigSpace!=NULL);
+
+ const TUint8 headerTypeByte = iConfigSpace->Read8(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
+//
+
--- /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 <e32cmn.h>
+
+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<TInt>& 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<DPciBridge> iPciBridges; //!< All the bridges on the system
+ static RPointerArray<TPciFunction> 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
--- /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 <variant.mmh>
+#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
--- /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 <kernel/kernel.h>
+
+/**
+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<TDfcFn>(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<TMemorySpace> iMemorySpaces;
+ TBool iIsBridge;
+ TBool iIsMultiFunc;
+ };
+
+
+#endif //_PCI_PRIV_H
--- /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 <pci.h>
+#include <naviengine_priv.h>
+#include <naviengine.h>
+#include <kernel/cache.h>
+#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<DPlatChunkHw>& 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<DPlatChunkHw> 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; i<count; ++i)
+ {
+ TEST_KERRNONE(Pci::RemoveChunk(func, chunkList[i]));
+ }
+ chunkList.Close();
+ }
+
+void TestPciMemoryAccess(TLinAddr aVirt, TUint32 aPciAddress, TUint aSize, TUint32 aAttributes)
+ {
+ __KTRACE_OPT(KPCI, Kern::Printf("\nTest accessing memory via PCI: attrs=0x%08x\n", aAttributes));
+
+ TEST(aPciAddress<=(0x2000-aSize)); //we need to fit within the first 8k of pci space or we'll be beyond the access window
+
+ __KTRACE_OPT(KPCI, Kern::Printf("write chunk from software"));
+ TUint8* const vByte=(TUint8*)aVirt;
+ memset(vByte, 0x5A, aSize);
+
+ __KTRACE_OPT(KPCI, Kern::Printf("confirm values"));
+ for(TUint i=0; i<aSize; ++i)
+ {
+ const TUint8 result=vByte[i];
+ TEST(result==0x5A);
+ }
+
+ __KTRACE_OPT(KPCI, Kern::Printf("read back chunk via PCI"));
+ //A standard DMA write would read from memory and *write* to peripheral
+ //in this case the PCI is doing a DMA read from memory.
+ Cache::SyncMemoryBeforeDmaWrite(aVirt, aSize, aAttributes);
+ TUint8* const pByte = (TUint8*)(KHwUsbHWindow+aPciAddress);
+ TEST(memcompare(vByte, aSize, pByte, aSize)==0);
+
+ //A standard DMA read would *read* from peripheral and write to memory.
+ Cache::SyncMemoryBeforeDmaRead(aVirt, aSize, aAttributes);
+ __KTRACE_OPT(KPCI, Kern::Printf("write chunk via PCI"));
+ memset(pByte,0xA5,aSize);
+
+ __KTRACE_OPT(KPCI, Kern::Printf("read back chunk via PCI"));
+ for(TUint i=0; i<aSize; ++i)
+ {
+ const TUint8 result=pByte[i];
+ TEST(result==0xA5);
+ }
+ Cache::SyncMemoryAfterDmaRead(aVirt, aSize);
+ __KTRACE_OPT(KPCI, Kern::Printf("read back chunk from software"));
+ TEST(memcompare(vByte, aSize, pByte, aSize)==0);
+ }
+
+void TestAddressConversion(TInt aFunc, TUint32 aPciAddr, TUint32 aPhysAddr, TInt32 aSize)
+ {
+ //round up size of region to what its equivilent pci region would be
+ if(aSize<KMinOutboundWindow)
+ aSize=KMinOutboundWindow;
+ else
+ aSize=Clp2(aSize); //round up to next Power of 2.
+
+
+ __KTRACE_OPT(KPCI, Kern::Printf("testing Pci<-->Phys 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<TInt> 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<size; i+=4)
+ {
+ __KTRACE_OPT(KPCI, Kern::Printf("%08x %02xH", cs.Read32(i), i));
+ }
+
+ __KTRACE_OPT(KPCI, Kern::Printf("DNaviEnginePci: Dumping OHCI memory space"));
+ size=ms.Size();
+ for(TUint i=0; i<size; i+=4)
+ {
+ __KTRACE_OPT(KPCI, Kern::Printf("%08x %02xH", ms.Read32(i), i));
+ }
+
+ //this will cause a master abort if it touches any unallocated PCI memory, which is likely.
+#ifdef CAUSE_ERROR
+ __KTRACE_OPT(KPCI, Kern::Printf("Dump all of PCI space"));
+ TUint32* pciSpace=(TUint32*)KHwUsbHWindow;
+ for(TInt i=0; i<0x2000; ++i)
+ {
+ __KTRACE_OPT(KPCI, Kern::Printf("%08x %02xH", pciSpace[i], i));
+ }
+#endif
+ Kern::Printf("Dump PCI bridge registers");
+ for(TInt i=0; i<0x100; i+=4)
+ {
+ __KTRACE_OPT(KPCI, Kern::Printf("%08x %02xH", reinterpret_cast<TUint32*>(KHwPciBridgeUsb)[i], i));
+ }
+ return r;
+ }
+
--- /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 <naviengine_priv.h>
+
+#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);
+ }
+
--- /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 <dfcs.h>
+
+#ifdef __USE_GPIO_STATIC_EXTENSION__
+// test standard extension handler number. *DO NOT USE*
+#define KTestStaticExtension 0x80000000
+#include <staticextension.h>
+#endif
+
+#include <gpio.h>
+
+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;
+ }
+
--- /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__*/
+
--- /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 <opensystemtrace.h>
+#endif
--- /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
--- /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 <variant.mmh>
+#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
--- /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 <comm.h>
+#include <assp.h>
+#include "uart16550_ne.h"
+#include <e32hal.h>
+
+__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);
+ }
--- /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 <drivers/comm.h>
+#include <assp.h>
+#include "../naviengine_priv.h"
+#include "../naviengine.h"
+#include "uart16550_ne.h"
+#include <e32hal.h>
+
+_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<<KNum16550Uarts);
+ iVersion=TVersion(KCommsMajorVersionNumber,KCommsMinorVersionNumber,KCommsBuildVersionNumber);
+ }
+
+
+TInt DDriverComm::Install()
+//
+// Install the driver
+//
+ {
+ // Allocate a kernel thread to run the DFC
+ TInt r = Kern::DynamicDfcQCreate(iDfcQ, KUart16550ThreadPriority, KUar16550tDriverThread);
+ if (r == KErrNone)
+ {
+#ifdef CPU_AFFINITY_ANY
+ NKern::ThreadSetCpuAffinity((NThread*)(iDfcQ->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;
+ }
+
--- /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 <e32def.h>
+
+//
+// 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<<K16550OffsetShift; // Transmit Holding Register
+const TUint8 K16550RXHROffset=0<<K16550OffsetShift; // Receive Holding Register
+const TUint8 K16550BDLoOffset=0<<K16550OffsetShift; // Baud Rate Divisor Low
+const TUint8 K16550IEROffset=1<<K16550OffsetShift; // Interrupt Enable Register
+const TUint8 K16550BDHiOffset=1<<K16550OffsetShift; // Baud Rate Divisor High
+const TUint8 K16550ISROffset=2<<K16550OffsetShift; // Interrupt Status Register
+const TUint8 K16550FCROffset=2<<K16550OffsetShift; // FIFO Control Register
+const TUint8 K16550LCROffset=3<<K16550OffsetShift; // Line Control Register
+const TUint8 K16550MCROffset=4<<K16550OffsetShift; // Modem Control Register
+const TUint8 K16550LSROffset=5<<K16550OffsetShift; // Line Status Register
+const TUint8 K16550MSROffset=6<<K16550OffsetShift; // Modem Status Register
+const TUint8 K16550ScratchpadOffset=7<<K16550OffsetShift; // Scratchpad Register
+
+// Interrupt Enable Register
+
+const TUint8 K16550IER_RDAI=1; // Received Data Available
+const TUint8 K16550IER_THREI=2; // Transmit Holding Register Empty
+const TUint8 K16550IER_RLSI=4; // Receive Line Status (error or break)
+const TUint8 K16550IER_MSI=8; // Modem Status
+
+// Interrupt Status Register
+
+const TUint8 K16550ISR_NotPending=1; // Not Interrupt Pending
+const TUint8 K16550ISR_IntIdMask=6; // Mask for Interrupt Identification
+const TUint8 K16550ISR_RDAI=4; // Received Data Available
+const TUint8 K16550ISR_THREI=2; // Transmit Holding Register Empty
+const TUint8 K16550ISR_RLSI=6; // Receive Line Status
+const TUint8 K16550ISR_MSI=0; // Modem Status
+const TUint8 K16550ISR_RxTimeout=8; // Set if FIFO timeout (in conjunction with RDA)
+
+// FIFO control Register
+
+const TUint8 K16550FCR_Enable=1; // Enable TX and RX FIFOs
+const TUint8 K16550FCR_RxReset=2; // Reset RX FIFO (self-clearing)
+const TUint8 K16550FCR_TxReset=4; // Reset TX FIFO (self-clearing)
+const TUint8 K16550FCR_TxRxRdy=8; //
+const TUint8 K16550FCR_RxTrig1=0; // RX FIFO triggers when >=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
--- /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 <variant.mmh>
+#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
--- /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 <e32keys.h>
+#include <comm.h>
+#include <assp.h>
+#include "../naviengine.h"
+#include <kernel/kern_priv.h>
+#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;
+ }
+
--- /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 <e32keys.h>
+#include <comm.h>
+#include <assp.h>
+#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; i<maxSeq; i++)
+ {
+ iCode[i]=0;
+ }
+ }
+
+TInt TSerialKeyboard::Create()
+ {
+// __KTRACE_OPT(KBOOT,Kern::Printf(_L("+TKeyboardSerial::Init"))) ;
+ TUint base;
+ TUint baud;
+
+ iKeyboardPort = GetSerialPort(baud);
+
+ switch(iKeyboardPort)
+ {
+ case 1: base=KHwBaseUart1; break;
+ case 2: base=KHwBaseUart2; break;
+ default: base=KHwBaseUart0;
+ iKeyboardPort = 0; //JTAG debug port, use port #0
+ }
+
+ __KTRACE_OPT(KBOOT,Kern::Printf("SERIAL KEYBOARD DRIVER: keyboard port=%d", iKeyboardPort ));
+
+ iUart = new T16550Uart;
+ if (iUart)
+ {
+ iUart->iBase = (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<iSeqNum; seqIndex++)
+ {
+ if (iCode[seqIndex] != escapeCodes[escCodeindex].seq[seqIndex])
+ {
+ break; // out of for loop
+ }
+ }
+ if (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;
+ }
--- /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__ */
--- /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 <variant.mmh>
+#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
--- /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 <e32keys.h>
+#include <comm.h>
+#include <assp.h>
+#include "../naviengine.h"
+#include <kernel/kern_priv.h>
+#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;
+ }
+
--- /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 <naviengine.h>
+
+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
+
+
--- /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 <variant.mmh>
+#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
--- /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
+
--- /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 <naviengine_priv.h>
+#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;
+ }
+
--- /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 <e32const.h>
+#include <platform.h>
+#include <e32hal.h>
+#include <assp.h>
+#include <kernel/kern_priv.h>
+
+
+
+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__
--- /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
--- /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 *)
+
--- /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 *)
+
--- /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 *)
+
--- /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 *)
+
--- /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 *)
+
--- /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
--- /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
--- /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)
+
--- /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 <r2> pages of NAND,
+; starting at page <r0>
+; placing data starting at <r1>
+;
+;-----------------------------------------------------------------------------------
+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
--- /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: <SMRIB size><SMRIB entries><...>
+ ; 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<<CPU number)
+ ORR r1, r1, r2 ; r1 = r1 | r2
+ STRH r1, [r0] ; write r1 back to the FLED register
+
+ ADD r6, r6, #1 ; r6 = CPU number of next AP
+ CMP r6, r5 ; if equal to number of CPUs, finished
+ BLO %BA1 ; else do next AP
+ ENDIF
+
+ LDMFD sp!, {pc}
+
+;*******************************************************************************
+; Output a character to the debug port
+;
+; Enter with :
+; R0 = character to output
+; R13 points to valid stack
+;
+; Leave with :
+; nothing modified
+;*******************************************************************************
+DoWriteC ROUT
+ IF CFG_DebugBootRom
+ STMFD sp!, {r1,r2,lr}
+ BL GetDebugPortBase ; r1 = base address of debug port
+
+ ; 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}
+ ELSE
+ MOV pc, lr
+ ENDIF
+
+
+ IF CFG_InitDebugPort
+;*******************************************************************************
+; Initialise the debug port
+;
+; Enter with :
+; R12 points to ROM header
+; There is no valid stack
+;
+; Leave with :
+; R0-R2 modified
+; Other registers unmodified
+;*******************************************************************************
+InitDebugPort ROUT
+ MOV r0, lr
+ BL GetDebugPortBase ; r1 = base address of debug port
+
+ LDR r2, [r12, #TRomHeader_iDebugPort]
+ MOVS r2, r2, LSL #24 ; C=1 if high speed, C=0 low speed
+
+ ; set up debug port
+ MOV r2, #0x83
+ STR r2, [r1, #Serial_LCR]
+ MOVCS r2, #KBaudRateDiv_230400
+ MOVCC 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
+
+;*******************************************************************************
+; Get the base address of the debug UART
+; It is uart0 (for TRomHeader::iDebugPort ==0) or uart1 otherwise
+; Returns physical or linear address, depending on the state of MMU.
+;
+; Enter with :
+; R12 points to ROM header
+; There may be no stack
+;
+; Leave with :
+; R1 = base address of port
+; No other registers modified
+;*******************************************************************************
+GetDebugPortBase ROUT
+ LDR r1, [r12, #TRomHeader_iDebugPort]
+ CMP r1, #0x100
+ BEQ %FA2 ; port 0 at 230400
+ CMP r1, #0
+ BNE %FA1 ; skip if not port 0
+2
+ GET_ADDRESS r1, KHwUART0Phys, Serial0LinBase
+ MOV pc, lr
+1
+ GET_ADDRESS r1, KHwUART1Phys, Serial1LinBase
+ MOV pc, lr
+
+ ENDIF ; CFG_InitDebugPort
+
+;*******************************************************************************
+; BOOT FUNCTION TABLE
+;*******************************************************************************
+
+BootTable
+ DCD DoWriteC ; output a debug character
+ DCD GetRamBanks ; get list of RAM banks
+ DCD SetupRamBank ; set up a RAM bank
+ DCD GetRomBanks ; get list of ROM banks
+ DCD SetupRomBank ; set up a ROM bank
+ DCD GetHwBanks ; get list of HW banks
+ DCD ReservePhysicalMemory ; reserve physical RAM if required
+ DCD GetParameters ; get platform dependent parameters
+ DCD FinalInitialise ; Final initialisation before booting the kernel
+ DCD HandleAllocRequest ; allocate memory
+ DCD GetPdeValue ; usually in generic code
+ DCD GetPteValue ; usually in generic code
+ DCD PageTableUpdate ; usually in generic code
+ DCD EnableMmu ; Enable the MMU (usually in generic code)
+
+ IF :DEF: CFG_USE_SHARED_MEMORY
+SharedMemory EQU 1
+ ELSE
+SharedMemory EQU 0
+ ENDIF
+
+ BTP_ENTRY CLIENT_DOMAIN, PERM_RORO, MEMORY_FULLY_CACHED, 1, 1, 0, SharedMemory ; ROM
+ BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_FULLY_CACHED, 0, 1, 0, SharedMemory ; kernel data/stack/heap
+ BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_FULLY_CACHED, 0, 1, 0, SharedMemory ; super page/CPU page
+ IF SMP
+ BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_UNCACHED, 0, 1, 0, SharedMemory ; page directory/tables
+ ELSE
+ BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_FULLY_CACHED, 0, 1, 0, SharedMemory ; page directory/tables
+ ENDIF
+ BTP_ENTRY CLIENT_DOMAIN, PERM_RONO, MEMORY_FULLY_CACHED, 1, 1, 0, SharedMemory ; exception vectors
+ BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_STRONGLY_ORDERED, 0, 1, 0, SharedMemory ; hardware registers
+ DCD 0 ; unused (minicache flush)
+ DCD 0 ; unused (maincache flush)
+ BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, MEMORY_FULLY_CACHED, 0, 1, 0, SharedMemory ; page table info
+ BTP_ENTRY CLIENT_DOMAIN, PERM_RWRW, MEMORY_FULLY_CACHED, 1, 1, 0, SharedMemory ; user RAM
+ BTP_ENTRY CLIENT_DOMAIN, PERM_RONO, MEMORY_STRONGLY_ORDERED, 1, 1, 0, SharedMemory ; temporary identity mapping
+ BTP_ENTRY CLIENT_DOMAIN, UNC_PERM, MEMORY_STRONGLY_ORDERED, 0, 1, 0, SharedMemory ; uncached
+
+
+ END
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/navienginebsp/ne1_tb/config.inc Tue Sep 28 18:00:05 2010 +0100
@@ -0,0 +1,175 @@
+;
+; 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, <value>
+
+; 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, <multiplier>
+; INIT_NUMERIC_CONSTANT CFG_KernelHeapBaseSize, <base>
+;
+; The initial kernel heap size is MAX( <base> + <multiplier> * N / 16, value specified in ROMBUILD )
+; where N is the total physical RAM size in pages.
+; <base> defaults to 24K and <multiplier> 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
--- /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 <variant.mmh>
+#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
--- /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__
--- /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 <variant.mmh>
+#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
--- /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
+
--- /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
+
--- /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
+
--- /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
+
--- /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
+
--- /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
+
--- /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
+
--- /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
+
--- /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 <variant.mmh>
+#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
+
--- /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 <variant.mmh>
+
+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
--- /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
+
+
--- /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 <e32std.h>
+#include <e32std_private.h>
+#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);
+ }
+
+
+
+
--- /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
--- /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;
+ }
--- /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 <e32def.h>
+#include <kernel/kernel.h>
+#include <kernel/kern_priv.h>
+#include <ethernet.h>
+#include <nkern.h>
+
+//
+// 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<KMaxEthernetPacket+32> &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<KMaxEthernetPacket+32> &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__
--- /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<KMaxEthernetPacket+32>& 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<KMaxEthernetPacket+32>& 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;
+ }
--- /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 <naviengine.h>
+#include "shared_ethernet.h"
+#include <drivers/gpio.h>
+#include <nkern.h>
+
+/**
+ * @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<KMaxEthernetPacket+32> &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<KMaxEthernetPacket+32> &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__
--- /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);
+ }
--- /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 <variant.mmh>
+#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
--- /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
--- /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 <kernel/hal_int.h>
+#include <u32std.h>
+
+//
+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;
+
+ }
+
--- /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 <variant.mmh>
+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
--- /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
+
--- /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
--- /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 <plat_priv.h>
+#include <kernel/kernboot.h>
+
+// -- 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<TAny*>(&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 <kernel\kernboot.h>
+ // 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;
+ }
--- /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 <hcrconfig.h>
+
+#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
+ };
+
--- /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
+
+
--- /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 <assp/naviengine/naviengine_priv.h>
+
+#include <ne1_tb/hcrconfig_mha.h>
+
+
+#endif // 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_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
+
+
--- /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 <drivers/hcr.h>
+
+
+
+// -- 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 <assp/naviengine/hcrconfig_assp.h>
+
+
+
+
+// -- MHA SETTING KEYS --------------------------------------------------------
+
+#include <ne1_tb/hcrconfig_mha.h>
+
+
+
+#endif // HCR_CONFIG_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 <drivers/hcr.h>
+
+
+
+// -- 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
+
--- /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 <variant.mmh>
+#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
+
--- /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 <drivers/iic_channel.h>
+
+
+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 <TCodecConfigData> iTransBuff;
+ TUint32 iCsiBusConfig;
+ };
+
+
+#endif /*CS42L51_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 <e32cmn.h>
+#include <kernel/kpower.h>
+
+//----------------------------------------------------------------------------
+// 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
+
--- /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 <flash_media.h>
+#include <naviengine.h>
+
+#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
--- /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 <kernel/kernel.h>
+
+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
--- /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
--- /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 <kernel/kpower.h>
+#include "variant.h"
+#include <e32btrace.h>
+#ifdef __SMP__
+#include <arm_gic.h>
+#endif
+#include <upd35001_timer.h>
+#if defined (__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__)
+#include <smppower/idlehelper.h>
+#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
+
--- /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
+ }
+
--- /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__
+
--- /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
--- /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 <naviengine.h>
+#include "powerresources.h"
+#include <resourcecontrol.h>
+
+#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__
+
--- /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 <dma.h>
+#include <soundsc.h>
+#include <i2s.h>
+#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__ */
--- /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
--- /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
--- /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 <variant.mmh>
+#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
--- /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 <variant.mmh>
+#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
--- /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 <variant.mmh>
+
+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
--- /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 <variant.mmh>
+#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
--- /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 <variant.mmh>
+#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
--- /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 <variant.mmh>
+#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
+
--- /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 <variant.mmh>
+#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
--- /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
--- /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 <variant.mmh>
+#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
--- /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 <nand_fbr_offset.h>
+#include <nanddevice.h>
+
+
+//
+// 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__
+
+
--- /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
--- /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
--- /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
--- /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
--- /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 <arm.h>
+#include <nkutils.h>
+#include <diag.h>
+
+#ifdef __SMP__
+#include <arm_gic.h>
+#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
+ }
--- /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 <arm.h>
+#include <nkutils.h>
+#include <diag.h>
+#include "kernboot.h"
+//#include <naviengine.h>
+
+#ifdef __SMP__
+#include <arm_gic.h>
+#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("<StartSystemTimer()"));
+
+ TInt i;
+ for (i=0; i<50; ++i)
+ {
+ DEBUGPRINT("Count %8d IRQ %02x", NET.iTimerCount, NET.iGTInterrupt);
+ }
+
+ ArmGic::Dump();
+ ArmGic::DumpCpuIfc();
+ }
+
+void HijackSystemTimer(NSchedulable* aTieTo)
+ {
+ TInt r = NKern::InterruptUnbind(SystemTimerInterruptHandle);
+ // need to accept KErrArgument because if the tied thread/group
+ // has gone away the interrupt will be unbound already and the
+ // handle is not valid
+ __NK_ASSERT_ALWAYS(r==KErrNone || r==KErrArgument);
+
+ NTimerQ& m=*(NTimerQ*)NTimerQ::TimerAddress();
+ TUint32 flags = NKern::EIrqBind_Count;
+ if (aTieTo)
+ flags |= NKern::EIrqBind_Tied;
+ r = NKern::InterruptBind(36-32, &TimerIsr, &m, flags, aTieTo);
+ __NK_ASSERT_ALWAYS(r>=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<ncpus; ++cpu)
+ {
+ TAny* stack = 0;
+ NThread* thread = 0;
+ stack = malloc(4096);
+ __NK_ASSERT_ALWAYS(stack);
+ memset(stack, (0xe1|(cpu<<1)), 4096);
+ thread = new NThread;
+ __NK_ASSERT_ALWAYS(thread);
+
+ SArmAPBootInfo info;
+ memclr(&info,sizeof(info));
+ info.iCpu = cpu;
+ info.iInitStackSize = 4096;
+ info.iInitStackBase = (TLinAddr)stack;
+ info.iMain = &ApMainGeneric;
+ info.iArgs[0] = (TAny*)thread;
+ info.iAPBootLin = spg.iAPBootPageLin;
+ info.iAPBootPhys = spg.iAPBootPagePhys;
+ info.iAPBootCodeLin = ::RomHeaderAddress;
+ info.iAPBootCodePhys = spg.iRomHeaderPhys;
+ info.iAPBootPageDirPhys = spg.iAPBootPageDirPhys;
+ TUint32 delta = cpu*0x2000;
+ info.iInitR13Fiq = TLinAddr(ss.iSSX.iFiqStackTop) + delta;
+ info.iInitR13Irq = TLinAddr(ss.iSSX.iIrqStackTop) + delta;
+ info.iInitR13Abt = TLinAddr(ss.iSSX.iAbtStackTop) + delta;
+ info.iInitR13Und = TLinAddr(ss.iSSX.iUndStackTop) + delta;
+ __KTRACE_OPT(KBOOT,DEBUGPRINT("iCpu=%08x", info.iCpu));
+ __KTRACE_OPT(KBOOT,DEBUGPRINT("iInitStackSize=%08x", info.iInitStackSize));
+ __KTRACE_OPT(KBOOT,DEBUGPRINT("iInitStackBase=%08x", info.iInitStackBase));
+ __KTRACE_OPT(KBOOT,DEBUGPRINT("iMain=%08x", info.iMain));
+ __KTRACE_OPT(KBOOT,DEBUGPRINT("iArgs=%08x %08x %08x %08x", info.iArgs[0], info.iArgs[1], info.iArgs[2], info.iArgs[3]));
+ __KTRACE_OPT(KBOOT,DEBUGPRINT("iAPBootLin=%08x", info.iAPBootLin));
+ __KTRACE_OPT(KBOOT,DEBUGPRINT("iAPBootPhys=%08x", info.iAPBootPhys));
+ __KTRACE_OPT(KBOOT,DEBUGPRINT("iAPBootCodeLin=%08x", info.iAPBootCodeLin));
+ __KTRACE_OPT(KBOOT,DEBUGPRINT("iAPBootCodePhys=%08x", info.iAPBootCodePhys));
+ __KTRACE_OPT(KBOOT,DEBUGPRINT("iAPBootPageDirPhys=%08x", info.iAPBootPageDirPhys));
+ __KTRACE_OPT(KBOOT,DEBUGPRINT("iInitR13Fiq=%08x", info.iInitR13Fiq));
+ __KTRACE_OPT(KBOOT,DEBUGPRINT("iInitR13Irq=%08x", info.iInitR13Irq));
+ __KTRACE_OPT(KBOOT,DEBUGPRINT("iInitR13Abt=%08x", info.iInitR13Abt));
+ __KTRACE_OPT(KBOOT,DEBUGPRINT("iInitR13Und=%08x", info.iInitR13Und));
+ TInt r = NKern::BootAP(&info);
+ __KTRACE_OPT(KBOOT,DEBUGPRINT("ret %d", r));
+ if (r==KErrNone)
+ {
+ while (__e32_atomic_load_acq32(&info.iArgs[1])==0)
+ __cpu_yield();
+ __KTRACE_OPT(KBOOT,DEBUGPRINT("CPU %d: OK NullThread=%08x InitialStack=%08x", cpu, thread, stack));
+ stack = 0;
+ thread = 0;
+ }
+ __NK_ASSERT_ALWAYS(r==KErrNone);
+ if (stack)
+ free(stack);
+ if (thread)
+ free(thread);
+ }
+ }
+#endif
+
+void Hw_Init3()
+ {
+ Interrupt_Init3();
+ StartSystemTimer();
+ }
+}
+
+extern "C" void NKCrashHandler(TInt aPhase, const TAny*, TInt)
+ {
+ if (aPhase==0)
+ {
+ return;
+ }
+ __finish();
+ }
+
+extern "C" void ExcFault(void* aExcInfo)
+ {
+#ifdef __SMP__
+ SubScheduler().iSSX.iExcInfo = aExcInfo;
+ SFullArmRegSet& a = *SubScheduler().iSSX.iRegs;
+#else
+ TheScheduler.i_ExcInfo = aExcInfo;
+ SFullArmRegSet& a = *(SFullArmRegSet*)TheScheduler.i_Regs;
+#endif
+ if (aExcInfo)
+ {
+ Arm::SaveState(a);
+ Arm::UpdateState(a, *(TArmExcInfo*)aExcInfo);
+ }
+ DumpFullRegSet(a);
+ NKern::NotifyCrash(0,0);
+ }
+
+/**
+Faults the system, noting file name and line number.
+
+Used from nanokernel code and in various __ASSERT macros.
+
+@param file The file name as a C string (__FILE__).
+@param line The line number (__LINE__).
+
+@see Kern::Fault()
+*/
+extern "C" void NKFault(const char* file, TInt line)
+ {
+ KPrintf("FAULT at line %d file %s", line, file);
+ NKern::NotifyCrash(0,0);
+ }
+
+
+void DebugPrint(const char* s, int l)
+ {
+ TInt i;
+#ifdef __SMP__
+ TInt irq=0;
+ if (!NKern::Crashed())
+ irq = DbgSpinLock.LockIrqSave();
+#endif
+ for (i=0; i<l; ++i)
+ PutC(*s++);
+#ifdef __SMP__
+ if (!NKern::Crashed())
+ DbgSpinLock.UnlockIrqRestore(irq);
+#endif
+ }
+
+TInt __timer_period()
+ {
+ return 1000;
+ }
+
+#ifdef __SMP__
+TInt __microseconds_to_timeslice_ticks(TInt us)
+ {
+ return NKern::TimesliceTicks(us);
+ }
+
+TInt __fast_counter_to_timeslice_ticks(TUint64 aFCdelta)
+ {
+ // fast counter freq = 400MHz/6
+ // timeslice freq = 400MHz/128
+ aFCdelta*=3;
+ aFCdelta>>=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("<Interrupt_Init1()"));
+ }
+
+extern "C" void Interrupt_Init2AP()
+ {
+ }
+
+extern "C" void Interrupt_Init3()
+ {
+ }
+
+
+#include <e32rom.h>
+
+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)
+ {
+ }
--- /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 <x86.h>
+#include <x86pc.h>
+#include <interrupts.h>
+
+#undef EXPORT_C
+#define EXPORT_C /* */
+
+extern "C" void CheckPoint();
+
+#define __CHECKPOINT() CheckPoint()
+
+#include "../specific/interrupts.cpp"
+#include "../specific/ioapic.cpp"
+
+#endif
--- /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 <variant.mmh>
+
+target VariantTarget(nktest,exe)
+targettype exe
+
+#ifdef SMP
+#include <nkernsmp/nkern_ext.mmh>
+#else
+#include <nkern/nkern_ext.mmh>
+#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
--- /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 <variant.mmh>
+#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
--- /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 <variant.mmh>
+#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
--- /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 <rebootdrv.h>
+#include <rebootdrv_ldd.h>
+#include <naviengine.h>
+#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;
+ }
+
+// @}
+
--- /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 <replacement_utils.h>
+#include <e32cmn.h>
+#include <cpudefs.h>
+#include <e32cia.h>
+
+#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__
--- /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 <replacement_utils.h>
+#include <klib.h>
+#include <e32cia.h>
+
+#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
--- /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
--- /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 <variant.mmh>
+#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
--- /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
--- /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 <rom/include/kernel.hby>
+#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
--- /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 <rom/include/ne1usbhost.iby>
+#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
--- /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__
--- /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
--- /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 <variant.mmh>
+#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
--- /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 <variant.mmh>
+#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
--- /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 <variant.mmh>
+#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
--- /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 <variant.mmh>
+#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
--- /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 <variant.mmh>
+#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
--- /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 <kernel/kernel.h>
+#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);
+ }
--- /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"
--- /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, <value>
+
+; 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, <multiplier>
+; INIT_NUMERIC_CONSTANT CFG_KernelHeapBaseSize, <base>
+;
+; The initial kernel heap size is MAX( <base> + <multiplier> * N / 16, value specified in ROMBUILD )
+; where N is the total physical RAM size in pages.
+; <base> defaults to 24K and <multiplier> 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
--- /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
+
+
--- /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__
+
--- /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 <variant.mmh>
+#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
--- /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 <naviengine.h>
+#include <i2s.h>
+
+_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<<KSoundScRxUnit0)|(1<<KSoundScTxUnit0);
+
+ // Set version number for this device.
+ iVersion=RSoundSc::VersionRequired();
+ }
+
+/**
+Destructor for the shared chunk sound PDD factory class.
+This function is called from the client thread context.
+*/
+DSoundScPddNE1_TB::~DSoundScPddNE1_TB()
+ {
+ __KTRACE_SND(Kern::Printf(">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);
+ }
--- /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 <navienginedma.h>
+#include <i2s.h>
+#include <nkern.h>
+#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; i<KMaxDmaRequests; i++)
+ {
+ delete iDmaRequest[i];
+ }
+
+ // Close the DMA channel.
+ if (iDmaChannel)
+ {
+ iDmaChannel->Close();
+ }
+ }
+
+/**
+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<TI2sConfigV01> 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;
+ }
+
--- /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 <variant.mmh>
+#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
--- /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 <kernel/kern_priv.h>
+#include <naviengine.h>
+#include <naviengine_priv.h>
+#include <gpio.h>
+#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<<KHsCS42L51DACControl_DATA_SEL); // also clearing freeze bit will update settings..
+
+ // let's rock!! - boost bass and treble a bit ;)
+ // values for nibbles change from 0: +12dB (maximum) boost,
+ // to 15:(minimum) -10.5dB boost. 8: 0dB - play 'as it is'
+ val = (5 << KHsCS42L51ALC_ToneCtrl_TREB) | (6
+ << KHsCS42L51ALC_ToneCtrl_BASS);
+ Write(KHwCS42L51ALC_ToneCtrl, val);
+
+ // power-up sequence.. - clear PDN ..after loading register settings..
+ Write(KHwCS42L51PwrCtrl, 0);
+
+ // This will return the error status, if any of Write() was not successful or KErrNone otherwise
+ return StopWrite();
+ }
+
+// this method is called from the sound-driver thread context to set the requested playback volume
+TInt RCS42AudioCodec::SetPlayVolume(TInt aVolume)
+ {
+ __KTRACE_SCODEC(Kern::Printf("RCS42AudioCodec::SetPlayVolume(%d)"));
+ // +12 db = 0001 1000 (24)
+ // 0db = 0000 0000 (0)
+ //-0.5db = 1111 1111 (255)
+ //-102db = 0001 1001 (25)
+ TUint8 volume = 0xff & (aVolume + KHbCS42L51ALC_Volume_Min);
+
+ StartWrite();
+ Write(KHwCS42L51ALC_Out_A_Volume, volume);
+ Write(KHwCS42L51ALC_Out_B_Volume, volume);
+ TInt r = StopWrite();
+
+ return r;
+ }
+
+// this method is called from the sound-driver thread context to set the requested record volume
+TInt RCS42AudioCodec::SetRecordVolume(TInt aVolume)
+ {
+ __KTRACE_SCODEC(Kern::Printf("RCS42AudioCodec::SetRecordVolume(%d)"));
+ // +12 db = 0001 1000 (24)
+ // 0db = 0000 0000 (0)
+ //-0.5db = 1111 1111 (255)
+ //-102db = 0001 1001 (25)
+ TUint8 volume = 0xff & (aVolume + KHbCS42L51ALC_Volume_Min);
+
+ StartWrite();
+ Write(KHwCS42L51ALC_ADC_A_MixVolume, volume);
+ Write(KHwCS42L51ALC_ADC_B_MixVolume, volume);
+ TInt r = StopWrite();
+
+ return r;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/navienginebsp/ne1_tb/specific/keyboard.cpp Tue Sep 28 18:00:05 2010 +0100
@@ -0,0 +1,736 @@
+/*
+* 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 polled keyboard
+* The code here implements a simple polled keyboard driver.
+* This is an alternative to the interrupt-driven driver in keyboard_interrupt.cpp.
+* This example assumes that we have a non-intelligent keyboard
+* consisting of a number of i/o lines arranged in a grid.
+* You can use this code as a starting point and modify it to suit
+* your hardware.
+*
+*/
+
+
+
+#include <naviengine.h>
+#include "platform.h"
+#include <kernel/kpower.h>
+#include <e32keys.h>
+
+
+
+// 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; row<KRows; row++)
+ iKeyBitMask[row] = 0;
+ }
+
+/**
+Determines whether any keys are being pressed by examining the
+array of bitmasks to determine whether any bits are set
+
+@return ETrue if one or more keys are being pressed
+*/
+TBool TKeyboardState::IsKeyReady()
+ {
+ for (TInt row=0; row<KRows; row++)
+ {
+ if (iKeyBitMask[row] != 0)
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+/**
+Scans the array of bitmasks and returns a keycode representing
+the first bit that it finds that is on.
+E.g. :
+if the first bit on the first row is set, then 1 is returned,
+if the third bit on the first row is set, then 3 is returned. etc.
+
+Once a bit is found it is cleared to avoid reading it again.
+
+NB Before calling this function, IsKeyReady() should be called
+to determine whether a key code is available.
+
+@return a 32-bit keycode representing a key that is currently pressed
+*/
+
+TUint32 TKeyboardState::GetKeyCode()
+ {
+ TInt keyNum = 0;
+ for (TInt row=0; row<KRows; row++)
+ {
+ TUint32 bitMask = 1;
+ for (TInt col=0; col<KColumns; col++)
+ {
+ if (iKeyBitMask[row] & bitMask)
+ {
+ iKeyBitMask[row] &= ~bitMask;
+ return keyNum;
+ }
+ bitMask<<= 1;
+ keyNum++;
+ }
+ }
+ return 0;
+ }
+
+/**
+Perform a bitwise AND between two TKeyboardState objects
+by AND-ing together all the 32-bit integers
+
+@return a new instance of a TKeyboardState object containing the result
+*/
+TKeyboardState TKeyboardState::operator&(const TKeyboardState& aState)
+ {
+ TKeyboardState state = *this;
+
+ for (TInt row=0; row<KRows; row++)
+ state.iKeyBitMask[row]&= aState.iKeyBitMask[row];;
+
+ return state;
+ }
+
+/**
+Perform a bitwise OR between two TKeyboardState objects
+by OR-ing together all the 32-bit integers
+
+@return a new instance of a TKeyboardState object containing the result
+*/
+TKeyboardState TKeyboardState::operator|(const TKeyboardState& aState)
+ {
+ TKeyboardState state = *this;
+
+ for (TInt row=0; row<KRows; row++)
+ state.iKeyBitMask[row]|= aState.iKeyBitMask[row];;
+
+ return state;
+ }
+
+/**
+Perform a bitwise NOT (one's complement) of a KeyboardState object
+by NOT-ing all the 32-bit integers
+
+@return a new instance of a TKeyboardState object containing the result
+*/
+TKeyboardState TKeyboardState::operator~()
+ {
+ TKeyboardState state = *this;
+
+ for (TInt row=0; row<KRows; row++)
+ state.iKeyBitMask[row] = ~state.iKeyBitMask[row];
+
+ return state;
+ }
+
+//
+//
+// TO DO: (optional)
+//
+// Modify this conversion table to suit your keyboard layout
+// EXAMPLE ONLY
+//
+
+const TUint8 convertCode[] =
+ {
+//Row 0 (bottom row)
+ EStdKeyLeftAlt , EStdKeyHash , EStdKeyNull , EStdKeyLeftCtrl ,
+ EStdKeyLeftFunc , EStdKeyEscape , '1' , '2' ,
+ '9' , '0' , EStdKeyMinus , EStdKeyEquals ,
+ EStdKeyNull , EStdKeyBackspace , EStdKeyNull , EStdKeyNull ,
+//Row 1
+ EStdKeyNull , EStdKeyBackSlash , EStdKeyLeftShift , EStdKeyNull ,
+ EStdKeyNull , EStdKeyDelete , EStdKeyNull , 'T' ,
+ 'Y' , 'U' , 'I' , EStdKeyEnter ,
+ EStdKeyRightShift , EStdKeyDownArrow , EStdKeyNull , EStdKeyNull ,
+//Row 2
+ EStdKeyNull , EStdKeyTab , EStdKeyNull , EStdKeyNull ,
+ EStdKeyNull , 'Q' , 'W' , 'E' ,
+ 'R' , 'O' , 'P' , EStdKeySquareBracketLeft ,
+ EStdKeyNull , EStdKeySquareBracketRight,EStdKeyNull , EStdKeyNull ,
+//Row 3
+ EStdKeyNull , 'Z' , EStdKeyNull , EStdKeyNull ,
+ EStdKeyNull , EStdKeyCapsLock , EStdKeyNull , EStdKeyNull ,
+ 'K' , 'L' , EStdKeySemiColon , EStdKeySingleQuote ,
+ EStdKeyNull , EStdKeyUpArrow , EStdKeyNull , EStdKeyNull ,
+//Row 4
+ EStdKeyNull , EStdKeyTab , EStdKeyNull , EStdKeyNull,
+ EStdKeyNull , 'Q' , 'W' , 'E' ,
+ 'R' , 'O' , 'P' , EStdKeySquareBracketLeft ,
+ EStdKeyNull , EStdKeySquareBracketRight, EStdKeyNull , EStdKeyNull ,
+//Row 5
+ EStdKeyNull , 'X' , EStdKeyNull , EStdKeyNull ,
+ EStdKeyNull , 'C' , 'V' , 'B' ,
+ 'N' , 'M' , EStdKeyComma , EStdKeyFullStop ,
+ EStdKeyNull , EStdKeySpace , EStdKeyNull , EStdKeyNull ,
+//Row 6
+ EStdKeyNull , EStdKeyNull , EStdKeyNull , EStdKeyNull ,
+ EStdKeyNull , '3' , '4' , '5' ,
+ '6' , '7' , '8' , EStdKeyMenu ,
+ EStdKeyNull , EStdKeyRightArrow , EStdKeyNull , EStdKeyNull
+ };
+
+
+
+
+// EXAMPLE ONLY
+const TKeyboard KConfigKeyboardType = EKeyboard_Full;
+const TInt KConfigKeyboardDeviceKeys = 0;
+const TInt KConfigKeyboardAppsKeys = 0;
+
+
+//
+// TO DO: (optional)
+//
+// Set the keyboard scan rate in milliseconds
+//
+
+// EXAMPLE ONLY
+const TInt KScanRate = 50; // poll every 1/20 of a second (i.e. every 50 milliseconds)
+
+
+_LIT(KLitKeyboard,"Keyboard");
+
+
+//
+// TO DO: (optional)
+//
+// Add any private functions and data you require
+//
+NONSHARABLE_CLASS(DKeyboardNE1_TB) : public DPowerHandler
+ {
+public:
+ DKeyboardNE1_TB();
+ TInt Create();
+
+ // from DPowerHandler
+ void PowerUp();
+ void PowerDown(TPowerState);
+
+private:
+ static void HandleMessage(TAny* aPtr);
+ void HandleMsg(TMessageBase* aMsg);
+
+ static TInt HalFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2);
+ TInt HalFunction(TInt aFunction, TAny* a1, TAny* a2);
+
+ static void PowerUpDfcFn(TAny* aPtr);
+ void PowerUpDfc();
+
+ static void PowerDownDfcFn(TAny* aPtr);
+ void PowerDownDfc();
+
+ static void TimerCallback(TAny* aDriver);
+ static void TimerDfcFn(TAny* aDriver);
+ void Poll();
+
+ void KeyboardInfo(TKeyboardInfoV01& aInfo);
+
+ void KeyboardOn();
+ void KeyboardOff();
+ void KeyboardPowerUp();
+
+private:
+ TDfcQue* iDfcQ;
+ TMessageQue iMsgQ;
+ TDfc iPowerUpDfc;
+ TDfc iPowerDownDfc;
+ TBool iKeyboardOn;
+ NTimer iTimer;
+ TInt iTimerTicks;
+ TDfc iTimerDfc;
+
+ // a bitmask indicating which keys were pressed down on the last timer tick
+ TKeyboardState iKeyStateLast;
+
+ // a bitmask indicating the set of keys for which we have sent an EKeyDown event
+ TKeyboardState iKeysDown;
+ };
+
+/**
+constructor
+*/
+DKeyboardNE1_TB::DKeyboardNE1_TB()
+ : DPowerHandler(KLitKeyboard),
+ iMsgQ(HandleMessage, this, NULL, 1),
+ iPowerUpDfc(PowerUpDfcFn, this, 6),
+ iPowerDownDfc(PowerDownDfcFn, this, 7),
+ iTimer(&DKeyboardNE1_TB::TimerCallback, (TAny*) this),
+ iTimerDfc(TimerDfcFn, this, 1)
+ {
+ // Convert the scan rate from milliseconds to nanokernel ticks (normally 1/64 of a second)
+ iTimerTicks = NKern::TimerTicks(KScanRate);
+ }
+
+/**
+Second-phase constructor
+Assigns queues for all the DFCs and starts the keyboard-polling timer
+
+Called by factory function at ordinal 0
+*/
+TInt DKeyboardNE1_TB::Create()
+ {
+ iDfcQ=Kern::DfcQue0();
+
+ iKeyboardOn = EFalse;
+
+ // install the HAL function
+ TInt r = Kern::AddHalEntry(EHalGroupKeyboard, DKeyboardNE1_TB::HalFunction, this);
+ if (r != KErrNone)
+ return r;
+
+ iTimerDfc.SetDfcQ(iDfcQ);
+
+ iPowerUpDfc.SetDfcQ(iDfcQ);
+ iPowerDownDfc.SetDfcQ(iDfcQ);
+ iMsgQ.SetDfcQ(iDfcQ);
+ iMsgQ.Receive();
+
+ // install the power handler
+ Add();
+
+ // Power up the device and start the timer
+ KeyboardPowerUp();
+
+ return r;
+ }
+
+/**
+Calback for the keyboard-polling timer
+Called in the context of an ISR
+
+@param aPtr A pointer to an instance of DKeyboardNE1_TB
+*/
+void DKeyboardNE1_TB::TimerCallback(TAny *aPtr)
+ {
+ // schedule a DFC
+ DKeyboardNE1_TB& k=*(DKeyboardNE1_TB*)aPtr;
+ k.iTimerDfc.Add();
+ }
+
+
+/**
+DFC scheduled by the keyboard-polling timer when it expires
+
+@param aPtr A pointer to an instance of DKeyboardNE1_TB
+*/
+void DKeyboardNE1_TB::TimerDfcFn(TAny* aPtr)
+ {
+ ((DKeyboardNE1_TB*)aPtr)->Poll();
+ }
+
+
+/**
+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<TKeyboardInfoV01> 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;
+ }
--- /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 <naviengine.h>
+#include <naviengine_priv.h>
+#include "iolines.h"
+#include "platform.h"
+#include <kernel/kpower.h>
+#include <e32keys.h>
+//
+//
+// 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<TKeyboardInfoV01> 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;
+ }
--- /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 <k32keys.h>
+
+#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;
+ }
--- /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 <naviengine.h>
+#include <naviengine_priv.h>
+#include <e32event.h>
+#include <e32event_private.h>
+#include <e32keys.h>
+#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<<line+4))
+// SW1 - is on scan line 1
+const TUint KHwKeyCodeArrowUp = 0x21; // SW1 Up
+const TUint KHwKeyCodeArrowRight = 0x22; // SW1 Right
+const TUint KHwKeyCodeArrowLeft = 0x24; // SW1 Left
+const TUint KHwKeyCodeArrowDown = 0x28; // SW1 Down
+const TUint KHwKeyCodeButtonCentre = 0x30; // SW1 Centre press
+const TUint KHwKeyCodeButtonLeft = 0x81; // SW2 - is on scan line 3
+const TUint KHwKeyCodeButtonRight = 0x41; // SW3 - is on scan line 2
+
+const TUint KHwKeyNumArrowUp = 0;
+const TUint KHwKeyNumArrowDown = 1;
+const TUint KHwKeyNumArrowLeft = 2;
+const TUint KHwKeyNumArrowRight = 3;
+const TUint KHwKeyNumButtonCentre = 4;
+const TUint KHwKeyNumButtonLeft = 5;
+const TUint KHwKeyNumButtonRight = 6;
+
+//#define __KTRACE(s) s
+#define __KTRACE(s)
+
+enum TKeyMode
+ {
+ EKeyModeS60 = 0,
+ EKeyModeTechview = 1,
+
+ // This must be the last entry in the list
+ EKeyModes
+ };
+
+class DNE1Keypad
+ {
+public:
+ DNE1Keypad();
+ TInt DoCreate();
+ static void GetScanCodes(TAny* aPtr);
+ void ProcessKey(TUint aKeyNum, TInt aState);
+
+private:
+
+ inline void AddEventForKey(TUint aKeyCode, TRawEvent::TType aEventType);
+ NTimer iKeyboardTimer;
+ TUint iKeyStates;
+ TKeyMode iKeyMode;
+ };
+
+
+/* Macro to detect is the key is shifted */
+#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))
+
+// modify this table to change the key mapping
+const TUint16 convertCode[][EKeyModes] =
+ {
+ // S60 TechView
+ { EStdKeyUpArrow, EStdKeyUpArrow, }, // SW1 Up
+ { EStdKeyDownArrow, EStdKeyDownArrow, }, // SW1 Down
+ { EStdKeyLeftArrow, EStdKeyLeftArrow, }, // SW1 Left
+ { EStdKeyRightArrow, EStdKeyRightArrow, }, // SW1 Right
+ { EStdKeyDevice3, EStdKeyEnter, }, // SW1 Centre Press
+ { EStdKeyDevice0, EStdKeyEscape, }, // SW2
+ { EStdKeyDevice1, EStdKeyMenu, }, // SW3
+ };
+
+void DNE1Keypad::AddEventForKey(TUint aKeyCode, TRawEvent::TType aEventType)
+ {
+ // convert character to keycode and shift, func, ctrl status
+ TUint16 code = convertCode[aKeyCode][iKeyMode];
+ TBool isShifted = ISSHIFTED(code);
+ TBool isFunced = ISFUNCED(code);
+ TBool isCtrled = ISCTRLED(code);
+ TUint8 stdKey = STDKEY(code);
+ TRawEvent e;
+
+ if (aEventType == TRawEvent::EKeyDown)
+ {
+ // post it as a sequence of events
+ 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(aEventType,stdKey,0);
+ Kern::AddEvent(e);
+
+ if (TRawEvent::EKeyUp)
+ {
+ 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 DNE1Keypad::ProcessKey(TUint aKeyNum, TInt aState)
+ {
+ // if the key was pressed last time AND key is now not pressed
+ if ((iKeyStates & (1<<aKeyNum)) && (aState == 0))
+ {
+ // send a key up event
+ __KTRACE(Kern::Printf("issue KeyUp for key %d ", aKeyNum));
+ AddEventForKey(aKeyNum,TRawEvent::EKeyUp);
+
+ // mark this key as released..
+ iKeyStates &= ~(1<<aKeyNum);
+ }
+ // if the key was NOT pressed last time AND key is now pressed
+ else if (!(iKeyStates & (1<<aKeyNum)) && (aState == 1))
+ {
+ // send a key down event
+ __KTRACE(Kern::Printf("issue KeyDown for key %d ", aKeyNum));
+ AddEventForKey(aKeyNum,TRawEvent::EKeyDown);
+
+ // mark this key as pressed down..
+ iKeyStates |= (1<<aKeyNum);
+ }
+ }
+
+
+void DNE1Keypad::GetScanCodes(TAny* aPtr)
+ {
+ DNE1Keypad* pD=(DNE1Keypad*)aPtr;
+
+ TInt keyRow, key=0;
+ for(keyRow = 1; keyRow < 4; ++keyRow)
+ {
+ AsspRegister::Write16(KHWKeySR, keyRow); // make line active..
+ TUint16 skey = AsspRegister::Read16(KHWKeyRL); // and scan it, 1=key was pressed..
+
+ if(skey)
+ {
+ key = (skey | (1<<(keyRow+4)));
+ }
+ }
+
+ // process each key in turn, passing the current state
+ pD->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;
+ }
--- /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<<BUS_WIDTH_PER_DEVICE) | (l<<BUS_WIDTH_PER_DEVICE*2) (l<<BUS_WIDTH_PER_DEVICE*3);
+#endif
+
+ // write the data length in words to the device(s)
+ *pF=l;
+
+ const TFLASHWORD* pS=(const TFLASHWORD*)(iData+iDataBufPos);
+
+ // write the data
+ TInt len;
+ for (len = l; len>=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<pE)
+ x&=*p++;
+ }
+ else
+ {
+ }
+ if (x == FLASH_ERASE_WORD_VALUE)
+ {
+ // erase OK
+ __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:VerifyErase OK"));
+ CHANGE_ERASE_STATE(EEraseIdle);
+
+ // complete the erase request
+ TInt r=iEraseError?KErrGeneral:KErrNone;
+ Complete(EReqErase,r);
+
+ // start any pending read or write requests
+ StartPendingRW();
+ }
+ else
+ {
+ // erase failed, so retry
+ __KTRACE_OPT(KLOCDRV,Kern::Printf("Flash:VerifyErase BAD"));
+ StartErase();
+ }
+ }
+ }
+
+void DMediaDriverFlashNE1_TB::DoFlashTimeout()
+ {
+ // TO DO: (optional)
+ // Take appropriate action to handle a timeout.
+ FLASH_FAULT(); // // EXAMPLE ONLY:
+ }
+
+DMediaDriverFlash* DMediaDriverFlash::New(TInt aMediaId)
+ {
+ return new DMediaDriverFlashNE1_TB(aMediaId);
+ }
+
+void DMediaDriverFlashNE1_TB::Isr(TAny* aPtr)
+ {
+ DMediaDriverFlashNE1_TB& d=*(DMediaDriverFlashNE1_TB*)aPtr;
+
+
+ // TO DO: (mandatory)
+ // Write to the timer hardware register(s) to
+ // clear the timer interrupt
+ //
+
+ d.IPostEvents(EPollTimer);
+ }
+
+void DMediaDriverFlashNE1_TB::IPostEvents(TUint32 aEvents)
+ {
+ iEvents|=aEvents;
+ iEventDfc.Add();
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/navienginebsp/ne1_tb/specific/monitor.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\monitor.cpp
+* Kernel crash debugger - NE1_TBVariant specific
+*
+*/
+
+
+
+#include <kernel/monitor.h>
+#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
+ }
+
--- /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 <kernel.h>
+#include "ne1_tb_power.h"
+#include <naviengine.h>
+#include <naviengine_priv.h>
+
+__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__
--- /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<<aCpu);
+ }
+
+#endif
+#endif
+
+
+//-/-/-/-/-/-/-/-/-/ class DNE1_TBPowerController /-/-/-/-/-/-/-/-/-/
+
+DNE1_TBPowerController::DNE1_TBPowerController()
+#if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__)
+ :iIdleHandler(this)
+#endif
+ {
+ Register(); // register Power Controller with Power Manager
+ TNE1_TBPowerController::RegisterPowerController(this);
+
+#if defined(__SMP__) && !defined(__NO_IDLE_HANDLER_PIL__)
+ // Register idle handler
+ if ((AsspRegister::Read32(KHwRoGpio_Port_Value) & (0x1<<27)))
+ {
+ __PM_ASSERT_ALWAYS(KErrNone==iIdleHandler.Initialise());
+ }
+ else
+ {
+ // press and hold User Switch 0 / INT0 (SW3) on boot
+ // to disable idle tick suppression
+ Kern::Printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+ Kern::Printf("!!!!!!!!!!!! NOT DOING ITS !!!!!!!!!!!");
+ Kern::Printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
+ }
+#endif
+ }
+
+void DNE1_TBPowerController::CpuIdle()
+ {
+ Arch::TheAsic()->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<iOriginalTimerExpire)
+ {
+ //We woke up before first tick expired
+ ticksSlept=0;
+ timeToNextInterruptDelta=iOriginalTimerExpire-timeIn;
+ }
+
+
+ if (timeToNextInterruptDelta < KMinTimeToTick)
+ {
+ // This should not happen on normal timer expiries as we should be be programmed to wake
+ // well before the next timer expiry which therefore means that ie we need to make sure that
+ // wake up times are always larger than this KMinTimeToTick
+ // However a WakeupEvent could have resulted in us waking close potential tick
+ // skip a tick
+ ticksSlept++;
+ timeToNextInterruptDelta +=KCyclesPerTick;
+ }
+ TUint32 timeToNextInterrupt = timeIn+timeToNextInterruptDelta;
+
+//while(timeToNextInterrupt==KWakeUpBeforeTick);
+
+
+ NET.iTimerReset = timeToNextInterrupt;
+ __e32_io_completion_barrier();
+ NTimerQ::Advance(ticksSlept);
+ // restart stopped 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);
+
+ TUint32 t2 = T2.iTimerCount;
+ TUint32 t1 = T1.iTimerCount;
+
+ // because timers at started one after the other
+ // there a certain amount of error accumulated in the diffence between them
+ // we need to take into account this error level when restarting them
+ // so that we can ensure the error does not grow
+ // note sleep time cannot exceed 0xffffff00
+ TUint32 error = (t1-t2)&0xff;
+ TUint32 remainder = 0xffffff00-t1;
+ if (remainder > 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<<pC->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<<targetCpu;
+ PMBTRACE4(KRetireCore,0x11,targetCpu);
+ targetCpuMask <<= ((KIntIdOstMatchMsTimer %4)<<3);
+ TUint32 clear = ~(0xff << ((KHwBaseGlobalIntDist%4)<<3));
+ GicDistributor* GIC = (GicDistributor*) KHwBaseGlobalIntDist;
+ GIC->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<<pC->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;
+ }
+
--- /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 <naviengine_priv.h>
+
+/** 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;
+ }
+
+
+
+
+
+
+
--- /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;
+ }
+
+
--- /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 <e32cia.h>
+#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
--- /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 <videodriver.h>
+#include <xyin.h>
+#include "ne1_tb_power.h"
+#include <naviengine_lcd.h>
+#include <d32ethernet.h>
+
+//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("<NE1_TBVariant::Init3()"));
+ }
+
+void Variant::Init3()
+//
+// Phase 3 initialisation
+//
+ {
+ __KTRACE_OPT(KHARDWARE, 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("<Variant::Init3"));
+ }
+
+EXPORT_C TUint Variant::BaseLinAddress()
+ {
+ return((TUint)iBaseAddress);
+ }
+
+EXPORT_C void Variant::MarkDebugPortOff()
+ {
+ TheVariant.iDebugInitialised=EFalse;
+ }
+
+void NE1_TBVariant::Idle()
+//
+// The NULL thread idle loop
+//
+ {
+ // Idle the CPU, suppressing the system tick if possible
+
+ //
+ // TO DO: (optional)
+ //
+ // Idle Tick supression:
+ // 1- obtain the number of idle Ticks before the next NTimer expiration (NTimerQ::IdleTime())
+ // 2- if the number of Ticks is large enough (criteria to be defined) reset the Hardware Timer
+ // to only interrupt again when the corresponding time has expired.
+ // 2.1- the calculation of the new value to program the Hardware Timer with should take in
+ // consideration the rounding value (NTimerQ::iRounding)
+ // 3- call the low level Sleep function (e'g. Bootstrap: address in iIdleFunction)
+ // 4- on coming back from Idle need to read the Hardware Timer and determine if woken up due to
+ // timer expiration (system time for new match<=current system time<system time for new match-tick period)
+ // or some other Interrupt.
+ // 4.1- if timer expiration, adjust System Time by adding the number of Ticks suppressed to NTimerQ::iMsCount
+ // 4.2- if other interrupt, calculate the number of Ticks skipped until woken up and adjust the System Time as
+ // above
+ //
+ // Support for different Sleep Modes:
+ // Often the Sleep mode a platform can go to depends on how many resources such as clocks/voltages can be
+ // turned Off or lowered to a suitable level. If different Sleep modes are supported this code may need
+ // to be able to find out what power resources are On or Off or used to what level. This could be achieved by
+ // enquiring the Resource Manager (see \ne1_tb\inc\ne1_tb_power.h).
+ // Then a decision could be made to what Sleep level we go to.
+ //
+ // Example calls:
+ // Obtain the number of Idle Ticks before the next NTimer expiration
+ // TInt aTicksLeft = NTimerQ::IdleTime();
+ // ...
+ // Find out the deepest Sleep mode available for current resource usage and sleeping time
+ // NE1_TBResourceManager* aManager = TNE1_TBPowerController::ResourceManager();
+ // NE1_TBResourceManager::TSleepModes aMode = aManager -> 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<NE1_TBVariant*>(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
--- /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 <assp.h>
+#include <naviengine.h>
+#include <videodriver.h>
+#include "mconf.h"
+#include <xyin.h>
+#include "lcdgce.h"
+
+#ifdef USE_PEN_INTERRUPTS
+#include <gpio.h>
+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()
+ {
+ }
+
+
--- /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
--- /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
--- /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 <drivers/iic_transaction.h>
+#include "csi_master.h"
+#include "csi_slave.h"
+#else
+#include <drivers/iic.h>
+#endif
+#include <drivers/iic_channel.h>
+#include <drivers/gpio.h>
+#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<TCapsIicClient> 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<TConfigSpiV01> 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<TConfigSpiV01> 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<TConfigSpiV01> header(TestHeader);
+
+ TBuf8<KTrBuf1Length> transBuf1;
+ TBuf8<KTrBuf2Length> 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<TConfigSpiV01> 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<TConfigSpiV01> 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<KTrasferBufferLength> trBuf1;
+ TBuf8<KTrasferBufferLength> 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<KTrasferBufferLength> trBuf3;
+ TBuf8<KTrasferBufferLength> 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<KTrasferBufferLength> trBuf1;
+ TBuf8<KTrasferBufferLength> trBuf2;
+ TBuf8<KTrasferBufferLength> 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<KTrasferBufferLength> trBuf4;
+ TBuf8<KTrasferBufferLength> trBuf5;
+ TBuf8<KTrasferBufferLength> 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<TConfigSpiV01> header(TestHeader);
+
+ TBuf8<KMaxSlaveTestBufferSize> txBuf; // buffer..
+ TBuf8<KMaxSlaveTestBufferSize> 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<TConfigSpiV01> 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;
+ }
+
--- /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 <drivers/iic.h>
+#include <drivers/iic_channel.h>
+#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 <TConfigSpiV01> 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<RCS42AudioCodec::TCodecConfigData> 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<KMaxSlaveTestBufferSize> iTxBuf; // buffer..
+ TBuf8<KMaxSlaveTestBufferSize> 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 <int dim>
+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<dim; ++i)
+ {
+ iBuffers[i] = NULL;
+ iTransfers[i] = NULL;
+ }
+ }
+
+ inline TIicBusTransfer* GetTransfer(TInt index)
+ {
+ // __ASSERT_DEBUG(index >= 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<dim; ++i)
+ {
+ delete iBuffers[i];
+ delete iTransfers[i];
+ }
+ }
+
+ DThread* iClient;
+ TRequestStatus* iReqStatus;
+
+ // all following need to be freed
+ TConfigSpiBufV01* iHeader;
+ TIicBusCallback *iCallback;
+
+ // to store buffers..
+ HBuf8* iBuffers[dim];
+
+ // to store transfers..
+ TIicBusTransfer* iTransfers[dim];
+
+ };
+#endif /*MASTER_MODE*/
+
+#endif /* __KERNEL_MODE__ */
+
+#endif /* __D_CSI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/navienginebsp/ne1_tb/test/csi/t_csi.cpp Tue Sep 28 18:00:05 2010 +0100
@@ -0,0 +1,440 @@
+/*
+* 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 <e32test.h>
+#include <e32ver.h>
+#include <e32cmn.h>
+#include <e32def.h>
+#include <e32def_private.h>
+#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<TSpiWordWidth> (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;
+ }
+
--- /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 <variant_test.mmh>
+#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
--- /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 <variant_test.mmh>
+#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
--- /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 <variant_test.mmh>
+
+#include "../../../../../os/kernelhwsrv/kerneltest/e32test/group/d_frqchg.mmh"
--- /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 <variant_test.mmh>
+#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
--- /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
--- /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 <variant_test.mmh>
+#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
--- /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 <naviengine_priv.h>
+#include <gpio.h>
+#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;
+ }
+
--- /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 <e32def.h>
+#include <e32cmn.h>
+#include <e32ver.h>
+
+#ifndef __KERNEL_MODE__
+#include <e32std.h>
+#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__
+
--- /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__
+
--- /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 <e32test.h>
+#include <e32ver.h>
+#include <e32def_private.h>
+#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;
+ }
+
--- /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
--- /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
--- /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
--- /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
--- /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
--- /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
+
+
--- /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
--- /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 <kernel/kernel.h>
+#include <kernel/kern_priv.h>
+#include <pci.h>
+#include <naviengine.h>
+#include <kernel/cache.h>
+#include "allocator.h"
+#include "pci-ne.h"
+#include "pci_priv.h"
+#include <platform.h>
+#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<TChunkCleanup*>(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<TPciDevice> devPckg(dev);
+ TInt r = Kern::ThreadDesRead(&Kern::CurrentThread(), aInfo, devPckg, 0, KChunkShiftBy0);
+ if(r != KErrNone)
+ return r;
+
+ NKern::ThreadEnterCS();
+ RArray<TInt> 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<TPciTestInfo> info(iTestInfo);
+ Kern::KUDesPut(dest, info);
+ return KErrNone;
+ }
+ case EAccessConfigSpace:
+ {
+ TPckgBuf<TUserConfigSpace> pckg;
+ Kern::KUDesGet(pckg, *reinterpret_cast<TDes8*>(a1));
+
+ TAddrSpace* configSpace = Pci::GetConfigSpace(iFunction);
+ if(configSpace == NULL)
+ {
+ Kern::PanicCurrentThread(KPciTest, KErrGeneral);
+ return KErrGeneral;
+ }
+ return pckg().KRun(*configSpace);
+ }
+ case EAccessMemorySpace:
+ {
+ TPckgBuf<TUserMemorySpace> pckg;
+ Kern::KUDesGet(pckg, *reinterpret_cast<TDes8*>(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<TPciChunkCreateInfo> pckg;
+ Kern::KUDesGet(pckg, *reinterpret_cast<TDes8*>(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;
+ }
--- /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 <e32std.h>
+#define __E32TEST_EXTENSION__
+#include <e32test.h>
+#include "t_pci.h"
+#include <assp/naviengine/pci.h>
+
+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<TPciDevice> devicePkg(aDevice);
+ return DoCreate(KPciLddFactory, TVersion(), KNullUnit, NULL, &devicePkg);
+ }
+
+inline TInt RPci::GetTestInfo(TPciTestInfo& aTestInfo)
+ {
+ TPckg<TPciTestInfo> info(aTestInfo);
+ return DoControl(EGetTestInfo, &info);
+ }
+
+inline TInt RPci::RunUnitTests()
+ {
+ return DoControl(ERunUnitTests);
+ }
+
+TUint RPci::AccessConfigSpace(const TUserConfigSpace& aCs)
+ {
+ TPckgC<TUserConfigSpace> pkg(aCs);
+ return DoControl(EAccessConfigSpace, &pkg);
+ }
+
+TUint RPci::AccessMemorySpace(const TUserMemorySpace& aMs)
+ {
+ TPckgC<TUserMemorySpace> 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<TPciChunkCreateInfo> 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<ChunkOpenFn FUNC>
+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<ChunkOpenFn FUNC>
+TInt CPciOpenChunkTest<FUNC>::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<ChunkOpenFn OPEN_FUNC>
+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;
+ }
+
--- /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 <e32def_private.h>
+
+// Following contents are carbon copy of \os\kernelhwsrv\kerneltest\e32test\misc\test_thread.h
+#include <e32test.h>
+#include <e32svr.h>
+#include <e32des8.h>
+#include <e32des8_private.h>
+#include <e32cmn.h>
+#include <e32cmn_private.h>
+#include <e32std.h>
+#include <e32std_private.h>
+
+
+_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<iIterations; i++)
+ {
+ test.Next(iName);
+ RunTest();
+ }
+ test.End();
+ }
+
+ virtual void RunTest() = 0;
+
+ virtual CTest* Clone() const = 0;
+
+ const TDesC& Name() const
+ {
+ return iName;
+ }
+
+protected:
+ CTest(const TDesC& aName, TInt aIterations)
+ :iIterations(aIterations)
+ {
+ iName.CreateL(aName);
+ }
+
+
+
+ CTest(const CTest& aOther)
+ :iIterations(aOther.iIterations)
+ {
+ iName.CreateL(aOther.iName);
+ }
+
+ //It would be useful to have an RTest member, but this can't be
+ //initialised untill the new thread is running as it will refer to
+ //the creating thread
+ RBuf iName;
+ const TInt iIterations;
+ };
+
+/**
+Make aNumberOfThreads copies of aTest and run
+each in its own thread
+
+@param test Reference to test object
+@param aTest Referance
+*/
+void MultipleTestRun(RTest& test, const CTest& aTest, TInt aNumberOfThreads)
+ {
+ RPointerArray<CTest> testArray;
+ RPointerArray<TTestThread> threadArray;
+
+ for(TInt i=0; i<aNumberOfThreads; i++)
+ {
+ test.Printf(_L("Create test thread"));
+ CTest* newTest = aTest.Clone();
+ test_NotNull(newTest);
+
+ TTestThread* thread = new TTestThread(aTest.Name(), *newTest);
+ test_NotNull(thread);
+
+ threadArray.AppendL(thread);
+ testArray.AppendL(newTest);
+ }
+
+ const TInt count = threadArray.Count();
+ for(TInt j=0; j<count; j++)
+ {
+ TTestThread* thread = threadArray[j];
+
+ TInt r = KErrNone;
+ TRAPD(leaveCode, r = thread->WaitForExitL());
+ 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
+
--- /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 <variant_test.mmh>
+
+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
--- /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 <variant_test.mmh>
+
+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
--- /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 <variant_test.mmh>
+
+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
--- /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 <kern_priv.h>
+#include <kernel.h>
+#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)
+ {
+ }
--- /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>
--- /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__
+
--- /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 <variant.mmh>
+#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
--- /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 <variant.mmh>
+#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
--- /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 <variant.mmh>
+#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
Binary file navienginebsp/tools/bootloader/flashldr.bin has changed
--- /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
--- /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 <filename> SPATH will save the source paths to a file
+// - DO <filename> 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"
+
--- /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
--- /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
--- /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"
+
+; <MCR|MRC> p15, <op1>, Rd, CRn, CRm, <op2>
+; BIT0-3:CRn
+; BIT4-7:CRm
+; BIT8-10:<op2>
+; BIT12-14:<op1>
+
+;*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
+
--- /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"
--- /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;
+
--- /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"
--- /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"
--- /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 <sym file> .. /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
--- /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
--- /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
+
--- /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"
--- /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"
+ )
+ )
--- /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"
+)
+
--- /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
--- /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
--- /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
+)
--- /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
--- /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
--- /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
--- /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"
--- /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
--- /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
--- /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)
+
--- /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
--- /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"
--- /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
--- /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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<SystemDefinition schema="3.0.0">
+ <package id="naviengine.nec" name="NaviEngine" levels="hw-if">
+ <collection id="navienginebsp" name="NaviEngine BSP" level="hw-if">
+ <component id="ne1_tb" name="NaviEngine 1 (Multiple)" introduced="^4" purpose="optional" filter="sf_build">
+ <unit bldFile="navienginebsp/ne1_tb"/>
+ </component>
+ <component id="sne1_tb" name="NaviEngine 1 (Single)" introduced="^4" purpose="optional" filter="sf_build">
+ <unit bldFile="navienginebsp/ne1_tb/single"/>
+ </component>
+ <component id="fne1_tb" name="NaviEngine 1 (Flexible)" introduced="^4" purpose="optional" filter="sf_build">
+ <unit bldFile="navienginebspflexible"/>
+ </component>
+ <component id="navienginebootldr" name="NaviEngine Boot Loader" introduced="^4" purpose="optional" filter="sf_build">
+ <unit bldFile="navienginebootldr"/>
+ </component>
+ <component id="navienginetest" name="NaviEngine Test" introduced="^4" purpose="optional" filter="test,sf_build">
+ <unit bldFile="navienginebsp/ne1_tb/test"/>
+ </component>
+ </collection>
+ </package>
+</SystemDefinition>