From 3d61697e688c99ff9265238b2eab474f7f1bcfc8 Mon Sep 17 00:00:00 2001 From: Octasic Inc Date: Wed, 23 Nov 2005 15:07:18 +0200 Subject: importing OCT612x-01.00-PR38 --- .../oct6100api/oct6100_api/oct6100_chip_open.c | 6097 ++++++++++++++++++++ 1 file changed, 6097 insertions(+) create mode 100644 software/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c (limited to 'software/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c') diff --git a/software/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c b/software/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c new file mode 100644 index 0000000..48987c0 --- /dev/null +++ b/software/octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.c @@ -0,0 +1,6097 @@ +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +File: oct6100_chip_open.c + + Copyright (c) 2001-2005 Octasic Inc. + +Description: + + This file contains the functions used to power-up the chip according to the + user's configuration. Also, the API instance is initialized to reflect the + desired configuration. + +This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is +free software; you can redistribute it and/or modify it under the terms of +the GNU General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +The OCT6100 GPL API is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with the OCT6100 GPL API; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + +$Octasic_Release: OCT612xAPI-01.00-PR38 $ + +$Octasic_Revision: 305 $ + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ + + +/***************************** INCLUDE FILES *******************************/ + +#include "octdef.h" + +#include "oct6100api/oct6100_defines.h" +#include "oct6100api/oct6100_errors.h" + +#include "apilib/octapi_bt0.h" +#include "apilib/octapi_llman.h" + +#include "oct6100api/oct6100_apiud.h" +#include "oct6100api/oct6100_chip_stats_inst.h" +#include "oct6100api/oct6100_tsi_cnct_inst.h" +#include "oct6100api/oct6100_events_inst.h" +#include "oct6100api/oct6100_conf_bridge_inst.h" +#include "oct6100api/oct6100_playout_buf_inst.h" + +#include "oct6100api/oct6100_mixer_inst.h" +#include "oct6100api/oct6100_channel_inst.h" +#include "oct6100api/oct6100_adpcm_chan_inst.h" +#include "oct6100api/oct6100_phasing_tsst_inst.h" +#include "oct6100api/oct6100_interrupts_inst.h" +#include "oct6100api/oct6100_remote_debug_inst.h" +#include "oct6100api/oct6100_debug_inst.h" +#include "oct6100api/oct6100_tlv_inst.h" +#include "oct6100api/oct6100_chip_open_inst.h" +#include "oct6100api/oct6100_api_inst.h" + +#include "oct6100api/oct6100_chip_stats_pub.h" +#include "oct6100api/oct6100_interrupts_pub.h" +#include "oct6100api/oct6100_tsi_cnct_pub.h" +#include "oct6100api/oct6100_events_pub.h" +#include "oct6100api/oct6100_conf_bridge_pub.h" +#include "oct6100api/oct6100_playout_buf_pub.h" + +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_adpcm_chan_pub.h" +#include "oct6100api/oct6100_phasing_tsst_pub.h" +#include "oct6100api/oct6100_remote_debug_pub.h" +#include "oct6100api/oct6100_chip_open_pub.h" +#include "oct6100api/oct6100_mixer_pub.h" +#include "oct6100api/oct6100_channel_pub.h" +#include "oct6100api/oct6100_debug_pub.h" + +#include "oct6100_chip_open_priv.h" +#include "oct6100_interrupts_priv.h" +#include "oct6100_chip_stats_priv.h" +#include "octrpc/rpc_protocol.h" +#include "oct6100_remote_debug_priv.h" +#include "oct6100_miscellaneous_priv.h" +#include "oct6100_memory_priv.h" +#include "oct6100_tsst_priv.h" +#include "oct6100_tsi_cnct_priv.h" +#include "oct6100_mixer_priv.h" +#include "oct6100_events_priv.h" +#include "oct6100_conf_bridge_priv.h" +#include "oct6100_playout_buf_priv.h" + +#include "oct6100_channel_priv.h" +#include "oct6100_adpcm_chan_priv.h" +#include "oct6100_phasing_tsst_priv.h" +#include "oct6100_tlv_priv.h" +#include "oct6100_debug_priv.h" +#include "oct6100_version.h" + + +/**************************** PUBLIC FUNCTIONS *****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100GetInstanceSizeDef + +Description: Retrieves the size of the required API instance structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pGetSize Structure containing API instance size. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100GetInstanceSizeDef( + tPOCT6100_GET_INSTANCE_SIZE f_pGetSize ) +{ + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100GetInstanceSize( + tPOCT6100_CHIP_OPEN f_pChipOpen, + tPOCT6100_GET_INSTANCE_SIZE f_pGetSize ) +{ + tOCT6100_API_INSTANCE_SIZES InstanceSizes; + UINT32 ulResult; + + /* Check user configuration for errors and conflicts. */ + ulResult = Oct6100ApiCheckChipConfiguration( f_pChipOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Calculate the instance size required for user's configuration. */ + ulResult = Oct6100ApiCalculateInstanceSizes( f_pChipOpen, &InstanceSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Return required size to user. */ + f_pGetSize->ulApiInstanceSize = InstanceSizes.ulApiInstTotal; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipOpenDef + +Description: Inserts default chip configuration parameters into the + structure pointed to by f_pChipOpen. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pChipOpen Structure containing user chip configuration. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ChipOpenDef( + tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + UINT32 i; + + f_pChipOpen->ulUserChipId = 0; + f_pChipOpen->fMultiProcessSystem = FALSE; + f_pChipOpen->pProcessContext = NULL; + + f_pChipOpen->ulMaxRwAccesses = 8; + + f_pChipOpen->pbyImageFile = NULL; + f_pChipOpen->ulImageSize = 0; + + f_pChipOpen->ulMemClkFreq = 133000000; /* 133 Mhz */ + f_pChipOpen->ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ; /* 33.33 Mhz */ + f_pChipOpen->fEnableMemClkOut = TRUE; + + f_pChipOpen->ulMemoryType = cOCT6100_MEM_TYPE_DDR; + f_pChipOpen->ulNumMemoryChips = 1; + f_pChipOpen->ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_64MB; + + /* Set the tail displacement to zero. */ + f_pChipOpen->ulTailDisplacement = 0; + + /* Disable acoustic echo by default. */ + f_pChipOpen->fEnableAcousticEcho = FALSE; + + /* Resource allocation parameters. */ + f_pChipOpen->ulMaxChannels = 672; + f_pChipOpen->ulMaxTsiCncts = 0; + f_pChipOpen->ulMaxBiDirChannels = 0; + f_pChipOpen->ulMaxConfBridges = 0; + f_pChipOpen->ulMaxFlexibleConfParticipants = 0; + f_pChipOpen->ulMaxPlayoutBuffers = 0; + + f_pChipOpen->ulMaxPhasingTssts = 0; + f_pChipOpen->ulMaxAdpcmChannels = 0; + f_pChipOpen->ulMaxTdmStreams = 32; + f_pChipOpen->fUseSynchTimestamp = FALSE; + for ( i = 0; i < 4; i++ ) + { + f_pChipOpen->aulTimestampTimeslots[ i ] = cOCT6100_INVALID_TIMESLOT; + f_pChipOpen->aulTimestampStreams[ i ] = cOCT6100_INVALID_STREAM; + } + f_pChipOpen->fEnableFastH100Mode = FALSE; + + /* Configure the soft tone event buffer. */ + f_pChipOpen->ulSoftToneEventsBufSize = 2048; + f_pChipOpen->fEnableExtToneDetection = FALSE; + + /* Configure the soft playout event buffer. */ + f_pChipOpen->ulSoftBufferPlayoutEventsBufSize = cOCT6100_INVALID_VALUE; + + /* Interrupt configuration. */ + f_pChipOpen->ulInterruptPolarity = cOCT6100_ACTIVE_LOW_POLARITY; + + f_pChipOpen->InterruptConfig.ulErrorMemoryConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulFatalGeneralConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulFatalMemoryConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulFatalMemoryConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulErrorH100Config = cOCT6100_INTERRUPT_NO_TIMEOUT; + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsConfig = cOCT6100_INTERRUPT_NO_TIMEOUT; + + f_pChipOpen->InterruptConfig.ulErrorMemoryTimeout = 100; + f_pChipOpen->InterruptConfig.ulFatalMemoryTimeout = 100; + f_pChipOpen->InterruptConfig.ulErrorH100Timeout = 100; + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsTimeout = 100; + f_pChipOpen->ulMaxRemoteDebugSessions = 1; + f_pChipOpen->ulTdmSampling = cOCT6100_TDM_SAMPLE_AT_3_QUARTERS; + for ( i = 0; i < cOCT6100_TDM_STREAM_MAX_GROUPS; i++ ) + f_pChipOpen->aulTdmStreamFreqs[ i ] = cOCT6100_TDM_STREAM_FREQ_8MHZ; + + + + f_pChipOpen->fEnableChannelRecording = FALSE; + f_pChipOpen->fEnableProductionBist = FALSE; + f_pChipOpen->ulNumProductionBistLoops = 1; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipOpen + +Description: Configures the chip according to the user specified + configuration f_pChipOpen. This function will perform all I/O + accesses necessary and initialize the API instance to reflect + the configuration. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipOpen Structure containing user chip configuration. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ChipOpen( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + tOCT6100_API_INSTANCE_SIZES InstanceSizes; + UINT32 ulStructSize; + UINT32 ulResult; + UINT32 ulTempVar; + + /* Check user chip configuration parameters for errors. */ + ulResult = Oct6100ApiCheckChipConfiguration( f_pChipOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the host system is multi-process or not and adjust instance accordingly. */ + if ( f_pChipOpen->fMultiProcessSystem != TRUE ) + { + /* Set pointer to tOCT6100_SHARED_INFO structure within instance. */ + ulStructSize = sizeof( tOCT6100_INSTANCE_API ); + mOCT6100_ROUND_MEMORY_SIZE( ulStructSize, ulTempVar ) + + f_pApiInstance->pSharedInfo = ( tPOCT6100_SHARED_INFO )(( UINT32 )f_pApiInstance + ulStructSize); + + /* Save the process context specified by the user. */ + f_pApiInstance->pProcessContext = f_pChipOpen->pProcessContext; + + + /* Create serialization object handles. */ + ulResult = Oct6100ApiCreateSerializeObjects( f_pApiInstance, f_pChipOpen->ulUserChipId ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Copy the configuration structure. */ + ulResult = Oct6100ApiCopyChipConfiguration( f_pApiInstance, f_pChipOpen ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Perform various calculations based on user chip configuration. */ + ulResult = Oct6100ApiInitializeMiscellaneousVariables( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Calculate the amount of memory needed for the API instance structure. */ + ulResult = Oct6100ApiCalculateInstanceSizes( f_pChipOpen, &InstanceSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Allocate the memory for the API instance structure internal pointers. */ + ulResult = Oct6100ApiAllocateInstanceMemory( f_pApiInstance, &InstanceSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the allocated instance structure memory. */ + ulResult = Oct6100ApiInitializeInstanceMemory( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the tone information structure. */ + ulResult = Oct6100ApiInitToneInfo( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Test the CPU registers. */ + ulResult = Oct6100ApiCpuRegisterBist( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Boot the FC2 PLL. */ + ulResult = Oct6100ApiBootFc2Pll( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Program the FC1 PLL. */ + ulResult = Oct6100ApiProgramFc1Pll( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Decode the key and bist internal memories. */ + ulResult = Oct6100ApiDecodeKeyAndBist( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Boot the FC1 PLL. */ + ulResult = Oct6100ApiBootFc1Pll( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Boot the SDRAM. */ + ulResult = Oct6100ApiBootSdram( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Bist the external memory. */ + ulResult = Oct6100ApiExternalMemoryBist( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the external memory. */ + ulResult = Oct6100ApiExternalMemoryInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Load the image into the chip. */ + ulResult = Oct6100ApiLoadImage( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the clock distribution registers. */ + ulResult = Oct6100ApiEnableClocks( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Program the NLP processor. */ + ulResult = Oct6100ApiProgramNLP( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + { + if ( ulResult == cOCT6100_ERR_OPEN_EGO_TIMEOUT ) + ulResult = Oct6100ApiProgramNLP( f_pApiInstance ); + } + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( f_pChipOpen->fEnableProductionBist == FALSE ) + { + /* Read all TLV fields present in external memory. */ + ulResult = Oct6100ApiProcessTlvRegion( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the H.100 interface. */ + ulResult = Oct6100ApiSetH100Register( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Write miscellaneous registers. */ + ulResult = Oct6100ApiWriteMiscellaneousRegisters( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Proceed with the rest only if the production BIST has not been requested. */ + if ( f_pChipOpen->fEnableProductionBist == FALSE ) + { + /* Configure the interrupt registers. */ + ulResult = Oct6100ApiIsrHwInit( f_pApiInstance, &f_pChipOpen->InterruptConfig ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the errors counters. */ + ulResult = Oct6100ApiChipStatsSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure all interrupts of the chip. */ + ulResult = Oct6100InterruptConfigureSer( f_pApiInstance, &f_pChipOpen->InterruptConfig, FALSE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Get revision number of chip. */ + ulResult = Oct6100ApiGetChipRevisionNum( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + + + /* Initialize the channels. */ + ulResult = Oct6100ApiInitChannels( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the mixer memory. */ + ulResult = Oct6100ApiInitMixer( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize the mixer memory. */ + ulResult = Oct6100ApiInitRecordResources( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Initialize free external memory for buffer playout. */ + ulResult = Oct6100ApiBufferPlayoutMemorySwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + } + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ChipCloseDef + +Description: Puts the chip into soft reset. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipClose Pointer to a tOCT6100_CHIP_CLOSE structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ChipCloseDef( + tPOCT6100_CHIP_CLOSE f_pChipClose ) +{ + f_pChipClose->ulDummyVariable = 0; + + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100ChipClose( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_CHIP_CLOSE f_pChipClose ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + WriteParams.ulWriteAddress = 0x100; + WriteParams.usWriteData = 0x0000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Destroy the allocated ressources used for serialization. */ + ulResult = Oct6100ApiDestroySerializeObjects( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100CreateLocalInstance + +Description: Creates a local instance for a process in a multi-process + host system. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pCreateLocal Structure used to create process' local instance. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100CreateLocalInstanceDef( + tPOCT6100_CREATE_LOCAL_INSTANCE f_pCreateLocal ) +{ + f_pCreateLocal->pApiInstShared = NULL; + f_pCreateLocal->pApiInstLocal = NULL; + f_pCreateLocal->pProcessContext = NULL; + f_pCreateLocal->ulUserChipId = 0; + + return cOCT6100_ERR_OK; +} + + +UINT32 Oct6100CreateLocalInstance( + tPOCT6100_CREATE_LOCAL_INSTANCE f_pCreateLocal ) +{ + tPOCT6100_INSTANCE_API pApiInstLocal; + UINT32 ulApiInstSize; + UINT32 ulTempVar; + UINT32 ulResult; + + /* Check user's structure for errors. */ + if ( f_pCreateLocal->pApiInstShared == NULL ) + return cOCT6100_ERR_MULTIPROC_API_INST_SHARED; + + if ( f_pCreateLocal->pApiInstLocal == NULL ) + return cOCT6100_ERR_MULTIPROC_API_INST_LOCAL; + + /* Get local pointer to local instance. */ + pApiInstLocal = f_pCreateLocal->pApiInstLocal; + + /* Assign pointers to local structure. */ + ulApiInstSize = sizeof( tOCT6100_INSTANCE_API ); + mOCT6100_ROUND_MEMORY_SIZE( ulApiInstSize, ulTempVar ) + + pApiInstLocal->pSharedInfo = ( tPOCT6100_SHARED_INFO )(( UINT32 )f_pCreateLocal->pApiInstShared + ulApiInstSize); + pApiInstLocal->pProcessContext = f_pCreateLocal->pProcessContext; + + /* Create serialization object handles needed. */ + ulResult = Oct6100ApiCreateSerializeObjects( pApiInstLocal, f_pCreateLocal->ulUserChipId ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100DestroyLocalInstance + +Description: Release local instance for a process in a multi-process + host system. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pDestroyLocal Structure used to destroy the process' local instance. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100DestroyLocalInstanceDef( + tPOCT6100_DESTROY_LOCAL_INSTANCE f_pDestroyLocal ) +{ + f_pDestroyLocal->ulDummy = 0; + + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100DestroyLocalInstance( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_DESTROY_LOCAL_INSTANCE f_pDestroyLocal ) +{ + UINT32 ulResult; + + /* Destroy the allocated ressources used for serialization. */ + ulResult = Oct6100ApiDestroySerializeObjects( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100GetHwRevision + +Description: Gets the hardware revision number of the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pGetHwRev Pointer to user structure in which to return revision + number. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100GetHwRevisionDef( + tPOCT6100_GET_HW_REVISION f_pGetHwRev ) +{ + f_pGetHwRev->ulUserChipId = cOCT6100_INVALID_CHIP_ID; + f_pGetHwRev->pProcessContext = NULL; + f_pGetHwRev->ulRevisionNum = cOCT6100_INVALID_VALUE; + + return cOCT6100_ERR_OK; +} + + +UINT32 Oct6100GetHwRevision( + tPOCT6100_GET_HW_REVISION f_pGetHwRev ) +{ + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 usReadData; + + /* Read the hardware revision register. */ + ReadParams.pProcessContext = f_pGetHwRev->pProcessContext; + + ReadParams.ulUserChipId = f_pGetHwRev->ulUserChipId; + ReadParams.pusReadData = &usReadData; + ReadParams.ulReadAddress = 0x17E; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + f_pGetHwRev->ulRevisionNum = ( usReadData >> 8 ) & 0xFF; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100FreeResources + +Description: This function closes all opened channels and frees all + specified global resources used by the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pFreeResources Pointer to user structure in which to choose what + to free. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100FreeResourcesDef( + tPOCT6100_FREE_RESOURCES f_pFreeResources ) +{ + f_pFreeResources->fFreeTsiConnections = FALSE; + f_pFreeResources->fFreeConferenceBridges = FALSE; + f_pFreeResources->fFreePlayoutBuffers = FALSE; + f_pFreeResources->fFreePhasingTssts = FALSE; + f_pFreeResources->fFreeAdpcmChannels = FALSE; + + return cOCT6100_ERR_OK; +} + + +UINT32 Oct6100FreeResources( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_FREE_RESOURCES f_pFreeResources ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100FreeResourcesSer( f_pApiInstance, f_pFreeResources ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ProductionBist + +Description: This function retrieves the current BIST status of the + firmware. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pProductionBist Pointer to user structure where the bist information + will be returned. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ProductionBistDef( + tPOCT6100_PRODUCTION_BIST f_pProductionBist ) +{ + f_pProductionBist->ulCurrentAddress = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulCurrentLoop = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulFailedAddress = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulReadValue = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulExpectedValue = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulBistStatus = cOCT6100_BIST_IN_PROGRESS; + f_pProductionBist->ulCurrentTest = cOCT6100_INVALID_VALUE; + + return cOCT6100_ERR_OK; +} + + +UINT32 Oct6100ProductionBist( + tPOCT6100_INSTANCE_API f_pApiInstance, + tPOCT6100_PRODUCTION_BIST f_pProductionBist ) +{ + tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj; + tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj; + UINT32 ulSerRes = cOCT6100_ERR_OK; + UINT32 ulFncRes = cOCT6100_ERR_OK; + + /* Set the process context of the serialize structure. */ + SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext; + ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext; + + /* Seize all list semaphores needed by this function. */ + SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY; + ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj ); + if ( ulSerRes == cOCT6100_ERR_OK ) + { + /* Call the serialized function. */ + ulFncRes = Oct6100ProductionBistSer( f_pApiInstance, f_pProductionBist ); + } + else + { + return ulSerRes; + } + + /* Release the seized semaphores. */ + ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj ); + + /* If an error occured then return the error code. */ + if ( ulSerRes != cOCT6100_ERR_OK ) + return ulSerRes; + if ( ulFncRes != cOCT6100_ERR_OK ) + return ulFncRes; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetVersion + +Description: Retrieves the API version. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pApiGetVersion Pointer to structure that will receive version information. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiGetVersionDef( + tPOCT6100_API_GET_VERSION f_pApiGetVersion ) +{ + UINT32 i; + + /* Initialize the string. */ + for ( i = 0; i < cOCT6100_API_VERSION_STRING_LENGTH; i++ ) + f_pApiGetVersion->achApiVersion[ i ] = 0; + + return cOCT6100_ERR_OK; +} + +UINT32 Oct6100ApiGetVersion( + tPOCT6100_API_GET_VERSION f_pApiGetVersion ) +{ + /* Copy API version information to user. */ + Oct6100UserMemCopy( f_pApiGetVersion->achApiVersion, cOCT6100_API_VERSION, sizeof(cOCT6100_API_VERSION) ); + + return cOCT6100_ERR_OK; +} + + +/*************************** PRIVATE FUNCTIONS *****************************/ + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCheckChipConfiguration + +Description: Checks the user chip configuration structure for errors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- + +f_pChipOpen Pointer to chip configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiCheckChipConfiguration( + IN tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + UINT32 ulTempVar; + UINT32 i; + + /*-----------------------------------------------------------------------------*/ + /* Check general parameters. */ + if ( f_pChipOpen->fMultiProcessSystem != TRUE && + f_pChipOpen->fMultiProcessSystem != FALSE ) + return cOCT6100_ERR_OPEN_MULTI_PROCESS_SYSTEM; + + if ( f_pChipOpen->ulMaxRwAccesses < 1 || + f_pChipOpen->ulMaxRwAccesses > 1024) + return cOCT6100_ERR_OPEN_MAX_RW_ACCESSES; + + /* Check the clocks. */ + if ( f_pChipOpen->ulUpclkFreq != cOCT6100_UPCLK_FREQ_33_33_MHZ && + f_pChipOpen->ulUpclkFreq != cOCT6100_UPCLK_FREQ_66_67_MHZ ) + return cOCT6100_ERR_OPEN_UP_CLK_FREQ; + + if ( f_pChipOpen->ulMemClkFreq != cOCT6100_MCLK_FREQ_133_MHZ && + f_pChipOpen->ulMemClkFreq != cOCT6100_MCLK_FREQ_125_MHZ && + f_pChipOpen->ulMemClkFreq != cOCT6100_MCLK_FREQ_117_MHZ && + f_pChipOpen->ulMemClkFreq != cOCT6100_MCLK_FREQ_108_MHZ && + f_pChipOpen->ulMemClkFreq != cOCT6100_MCLK_FREQ_100_MHZ && + f_pChipOpen->ulMemClkFreq != cOCT6100_MCLK_FREQ_92_MHZ && + f_pChipOpen->ulMemClkFreq != cOCT6100_MCLK_FREQ_83_MHZ && + f_pChipOpen->ulMemClkFreq != cOCT6100_MCLK_FREQ_75_MHZ ) + return cOCT6100_ERR_OPEN_MEM_CLK_FREQ; + + if ( f_pChipOpen->fEnableMemClkOut != TRUE && + f_pChipOpen->fEnableMemClkOut != FALSE ) + return cOCT6100_ERR_OPEN_ENABLE_MEM_CLK_OUT; + + /* Check the image file. */ + if ( f_pChipOpen->ulImageSize < cOCT6100_MIN_IMAGE_SIZE || + f_pChipOpen->ulImageSize > cOCT6100_MAX_IMAGE_SIZE ) + return cOCT6100_ERR_OPEN_IMAGE_SIZE; + + if ( f_pChipOpen->pbyImageFile == NULL ) + return cOCT6100_ERR_OPEN_IMAGE_FILE; + + /* Check the acoustic echo activation flag. */ + if ( f_pChipOpen->fEnableAcousticEcho != TRUE && + f_pChipOpen->fEnableAcousticEcho != FALSE ) + return cOCT6100_ERR_OPEN_ENABLE_ACOUSTIC_ECHO; + + /* Check the tail displacement parameter. */ + if ( f_pChipOpen->ulTailDisplacement > cOCT6100_MAX_TAIL_DISPLACEMENT ) + return cOCT6100_ERR_OPEN_TAIL_DISPLACEMENT; + + /*-----------------------------------------------------------------------------*/ + /* Check TDM bus configuration parameters. */ + for ( i = 0; i < 8; i++ ) + { + if ( f_pChipOpen->aulTdmStreamFreqs[ i ] != cOCT6100_TDM_STREAM_FREQ_2MHZ && + f_pChipOpen->aulTdmStreamFreqs[ i ] != cOCT6100_TDM_STREAM_FREQ_4MHZ && + f_pChipOpen->aulTdmStreamFreqs[ i ] != cOCT6100_TDM_STREAM_FREQ_8MHZ) + return cOCT6100_ERR_OPEN_TDM_STREAM_FREQS; + } + + if ( f_pChipOpen->ulTdmSampling != cOCT6100_TDM_SAMPLE_AT_3_QUARTERS && + f_pChipOpen->ulTdmSampling != cOCT6100_TDM_SAMPLE_AT_RISING_EDGE && + f_pChipOpen->ulTdmSampling != cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE ) + return cOCT6100_ERR_OPEN_TDM_SAMPLING; + + if ( f_pChipOpen->fEnableFastH100Mode != TRUE && + f_pChipOpen->fEnableFastH100Mode != FALSE ) + return cOCT6100_ERR_OPEN_FAST_H100_MODE; + + /*-----------------------------------------------------------------------------*/ + /* Check external memory configuration parameters. */ + if ( f_pChipOpen->ulMemoryType != cOCT6100_MEM_TYPE_SDR && + f_pChipOpen->ulMemoryType != cOCT6100_MEM_TYPE_DDR && + f_pChipOpen->ulMemoryType != cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + return cOCT6100_ERR_OPEN_MEMORY_TYPE; + + if ( f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_8MB && + f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_16MB && + f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_32MB && + f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_64MB && + f_pChipOpen->ulMemoryChipSize != cOCT6100_MEMORY_CHIP_SIZE_128MB ) + return cOCT6100_ERR_OPEN_MEMORY_CHIP_SIZE; + + if ( f_pChipOpen->ulMemoryChipSize == cOCT6100_MEMORY_CHIP_SIZE_8MB && + f_pChipOpen->ulMemoryType == cOCT6100_MEM_TYPE_DDR ) + return cOCT6100_ERR_OPEN_MEMORY_CHIP_SIZE; + + if ( f_pChipOpen->ulNumMemoryChips < 1 || + f_pChipOpen->ulNumMemoryChips > cOCT6100_MAX_NUM_MEMORY_CHIP ) + return cOCT6100_ERR_OPEN_MEMORY_CHIPS_NUMBER; + + /* Check the total memory size. */ + ulTempVar = f_pChipOpen->ulMemoryChipSize * f_pChipOpen->ulNumMemoryChips; + if ( ulTempVar < cOCT6100_MEMORY_CHIP_SIZE_16MB || + ulTempVar > cOCT6100_MEMORY_CHIP_SIZE_128MB ) + return cOCT6100_ERR_OPEN_TOTAL_MEMORY_SIZE; + + if ( f_pChipOpen->ulMaxTdmStreams != 4 && + f_pChipOpen->ulMaxTdmStreams != 8 && + f_pChipOpen->ulMaxTdmStreams != 16 && + f_pChipOpen->ulMaxTdmStreams != 32 ) + return cOCT6100_ERR_OPEN_MAX_TDM_STREAM; + + if ( f_pChipOpen->ulMaxTdmStreams > 8 && + f_pChipOpen->ulMemClkFreq == cOCT6100_MCLK_FREQ_75_MHZ ) + return cOCT6100_ERR_OPEN_MAX_TDM_STREAM; + + if ( f_pChipOpen->fUseSynchTimestamp != TRUE && + f_pChipOpen->fUseSynchTimestamp != FALSE ) + return cOCT6100_ERR_OPEN_USE_SYNCH_TIMESTAMP; + + if ( f_pChipOpen->fUseSynchTimestamp == TRUE ) + { + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_USE_SYNCH_TIMESTAMP; + } + + /*-----------------------------------------------------------------------------*/ + /* Check soft buffer for tone events size. */ + if ( f_pChipOpen->ulSoftToneEventsBufSize < cOCT6100_NUM_PGSP_EVENT_OUT || + f_pChipOpen->ulSoftToneEventsBufSize > cOCT6100_ABSOLUTE_MAX_NUM_PGSP_EVENT_OUT ) + return cOCT6100_ERR_OPEN_SOFT_TONE_EVENT_SIZE; + + if ( f_pChipOpen->fEnableExtToneDetection != TRUE && + f_pChipOpen->fEnableExtToneDetection != FALSE ) + return cOCT6100_ERR_OPEN_ENABLE_EXT_TONE_DETECTION; + + /* Check soft buffer for playout events size. */ + if ( ( f_pChipOpen->ulSoftBufferPlayoutEventsBufSize != cOCT6100_INVALID_VALUE ) + && ( f_pChipOpen->ulSoftBufferPlayoutEventsBufSize < cOCT6100_MIN_BUFFER_PLAYOUT_EVENT || + f_pChipOpen->ulSoftBufferPlayoutEventsBufSize > cOCT6100_MAX_BUFFER_PLAYOUT_EVENT ) ) + return cOCT6100_ERR_OPEN_SOFT_PLAYOUT_STOP_EVENT_SIZE; + + /*-----------------------------------------------------------------------------*/ + /* Check interrupt configuration parameters. */ + if ( f_pChipOpen->ulInterruptPolarity != cOCT6100_ACTIVE_LOW_POLARITY && + f_pChipOpen->ulInterruptPolarity != cOCT6100_ACTIVE_HIGH_POLARITY ) + return cOCT6100_ERR_OPEN_INTERRUPT_POLARITY; + + if ( f_pChipOpen->InterruptConfig.ulFatalGeneralConfig != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulFatalGeneralConfig != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_FATAL_GENERAL_CONFIG; + + if ( f_pChipOpen->InterruptConfig.ulFatalMemoryConfig != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulFatalMemoryConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pChipOpen->InterruptConfig.ulFatalMemoryConfig != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_FATAL_MEMORY_CONFIG; + + if ( f_pChipOpen->InterruptConfig.ulErrorMemoryConfig != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorMemoryConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorMemoryConfig != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_ERROR_MEMORY_CONFIG; + + if ( f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsConfig != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_ERROR_OVERFLOW_TONE_EVENTS_CONFIG; + + if ( f_pChipOpen->InterruptConfig.ulErrorH100Config != cOCT6100_INTERRUPT_NO_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorH100Config != cOCT6100_INTERRUPT_TIMEOUT && + f_pChipOpen->InterruptConfig.ulErrorH100Config != cOCT6100_INTERRUPT_DISABLE ) + return cOCT6100_ERR_OPEN_ERROR_H100_CONFIG; + + /* Check the timeout value. */ + if ( f_pChipOpen->InterruptConfig.ulFatalMemoryTimeout < 10 || + f_pChipOpen->InterruptConfig.ulFatalMemoryTimeout > 10000 ) + return cOCT6100_ERR_OPEN_FATAL_MEMORY_TIMEOUT; + + if ( f_pChipOpen->InterruptConfig.ulErrorMemoryTimeout < 10 || + f_pChipOpen->InterruptConfig.ulErrorMemoryTimeout > 10000 ) + return cOCT6100_ERR_OPEN_ERROR_MEMORY_TIMEOUT; + + if ( f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsTimeout < 10 || + f_pChipOpen->InterruptConfig.ulErrorOverflowToneEventsTimeout > 10000 ) + return cOCT6100_ERR_OPEN_ERROR_OVERFLOW_TONE_EVENTS_TIMEOUT; + + if ( f_pChipOpen->InterruptConfig.ulErrorH100Timeout < 10 || + f_pChipOpen->InterruptConfig.ulErrorH100Timeout > 10000 ) + return cOCT6100_ERR_OPEN_ERROR_H100_TIMEOUT; + + /*-----------------------------------------------------------------------------*/ + /* Check maximum resources. */ + + switch ( f_pChipOpen->ulMemClkFreq ) + { + case 133000000: + ulTempVar = 672; + break; + case 125000000: + ulTempVar = 624; + break; + case 117000000: + ulTempVar = 576; + break; + case 108000000: + ulTempVar = 528; + break; + case 100000000: + ulTempVar = 480; + break; + case 92000000: + ulTempVar = 432; + break; + case 83000000: + ulTempVar = 384; + break; + case 75000000: + ulTempVar = 336; + break; + default: + return cOCT6100_ERR_FATAL_DA; + } + + if ( f_pChipOpen->ulMaxChannels > ulTempVar ) + return cOCT6100_ERR_OPEN_MAX_ECHO_CHANNELS; + + if ( f_pChipOpen->ulMaxTsiCncts > cOCT6100_MAX_TSI_CNCTS ) + return cOCT6100_ERR_OPEN_MAX_TSI_CNCTS; + + if ( f_pChipOpen->ulMaxBiDirChannels > (f_pChipOpen->ulMaxChannels / 2) ) + return cOCT6100_ERR_OPEN_MAX_BIDIR_CHANNELS; + + if ( f_pChipOpen->ulMaxConfBridges > cOCT6100_MAX_CONF_BRIDGE ) + return cOCT6100_ERR_OPEN_MAX_CONF_BRIDGES; + + if ( f_pChipOpen->ulMaxFlexibleConfParticipants > cOCT6100_MAX_FLEX_CONF_PARTICIPANTS ) + return cOCT6100_ERR_OPEN_MAX_FLEXIBLE_CONF_PARTICIPANTS; + + if ( f_pChipOpen->ulMaxPlayoutBuffers > cOCT6100_MAX_PLAYOUT_BUFFERS ) + return cOCT6100_ERR_OPEN_MAX_PLAYOUT_BUFFERS; + + + + if ( f_pChipOpen->ulMaxPhasingTssts > cOCT6100_MAX_PHASING_TSST ) + return cOCT6100_ERR_OPEN_MAX_PHASING_TSSTS; + + if ( f_pChipOpen->ulMaxAdpcmChannels > cOCT6100_MAX_ADPCM_CHANNELS ) + return cOCT6100_ERR_OPEN_MAX_ADPCM_CHANNELS; + + if ( f_pChipOpen->ulMaxRemoteDebugSessions > 256 ) + return cOCT6100_ERR_OPEN_MAX_REMOTE_DEBUG_SESSIONS; + + + + + + /* Check the channel recording flag. */ + if ( f_pChipOpen->fEnableChannelRecording != TRUE && + f_pChipOpen->fEnableChannelRecording != FALSE ) + return cOCT6100_ERR_OPEN_DEBUG_CHANNEL_RECORDING; + + /* Check the enable production BIST flag. */ + if ( ( f_pChipOpen->fEnableProductionBist != TRUE ) + && ( f_pChipOpen->fEnableProductionBist != FALSE ) ) + return cOCT6100_ERR_OPEN_ENABLE_PRODUCTION_BIST; + + /* Check number of loops for the production BIST. */ + if ( f_pChipOpen->fEnableProductionBist == TRUE ) + { + if ( f_pChipOpen->ulNumProductionBistLoops == 0 ) + return cOCT6100_ERR_OPEN_NUM_PRODUCTION_BIST_LOOPS; + } + + /* If the production BIST has been requested, make sure all */ + /* other resources are disabled. */ + if ( f_pChipOpen->fEnableProductionBist == TRUE ) + { + /* All must be disabled. */ + f_pChipOpen->ulMaxChannels = 0; + f_pChipOpen->ulMaxTsiCncts = 0; + f_pChipOpen->fEnableChannelRecording = FALSE; + f_pChipOpen->ulMaxBiDirChannels = 0; + f_pChipOpen->ulMaxConfBridges = 0; + f_pChipOpen->ulMaxPlayoutBuffers = 0; + f_pChipOpen->ulSoftBufferPlayoutEventsBufSize = cOCT6100_INVALID_VALUE; + f_pChipOpen->ulMaxPhasingTssts = 0; + f_pChipOpen->ulMaxAdpcmChannels = 0; + + + } + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCopyChipConfiguration + +Description: Copies the chip configuration from the user supplied config + structure to the instance structure. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pChipOpen Pointer to chip configuration structure. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiCopyChipConfiguration( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_CHIP_OPEN f_pChipOpen ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + pSharedInfo->ChipConfig.ulUserChipId = f_pChipOpen->ulUserChipId; + pSharedInfo->ChipConfig.fMultiProcessSystem = (UINT8)( f_pChipOpen->fMultiProcessSystem & 0xFF ); + + pSharedInfo->ChipConfig.usMaxRwAccesses = (UINT16)( f_pChipOpen->ulMaxRwAccesses & 0xFFFF ); + + pSharedInfo->ChipConfig.pbyImageFile = f_pChipOpen->pbyImageFile; + pSharedInfo->ChipConfig.ulImageSize = f_pChipOpen->ulImageSize; + + pSharedInfo->ChipConfig.ulMemClkFreq = f_pChipOpen->ulMemClkFreq; + pSharedInfo->ChipConfig.ulUpclkFreq = f_pChipOpen->ulUpclkFreq; + + pSharedInfo->ChipConfig.byMemoryType = (UINT8)( f_pChipOpen->ulMemoryType & 0xFF ); + pSharedInfo->ChipConfig.byNumMemoryChips = (UINT8)( f_pChipOpen->ulNumMemoryChips & 0xFF ); + pSharedInfo->ChipConfig.ulMemoryChipSize = f_pChipOpen->ulMemoryChipSize; + + pSharedInfo->ChipConfig.usTailDisplacement = (UINT16)( f_pChipOpen->ulTailDisplacement & 0xFFFF ); + pSharedInfo->ChipConfig.fEnableAcousticEcho = (UINT8)( f_pChipOpen->fEnableAcousticEcho & 0xFF ); + /* Resource allocation parameters. */ + if ( f_pChipOpen->fEnableChannelRecording == TRUE && f_pChipOpen->ulMaxChannels == 672 ) + pSharedInfo->ChipConfig.usMaxChannels = (UINT16)( ( f_pChipOpen->ulMaxChannels - 1 ) & 0xFFFF ); + else + pSharedInfo->ChipConfig.usMaxChannels = (UINT16)( f_pChipOpen->ulMaxChannels & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxTsiCncts = (UINT16)( f_pChipOpen->ulMaxTsiCncts & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxBiDirChannels = (UINT16)( f_pChipOpen->ulMaxBiDirChannels & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxConfBridges = (UINT16)( f_pChipOpen->ulMaxConfBridges & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxFlexibleConfParticipants = (UINT16)( f_pChipOpen->ulMaxFlexibleConfParticipants & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxPlayoutBuffers = (UINT16)( f_pChipOpen->ulMaxPlayoutBuffers & 0xFFFF ); + + pSharedInfo->ChipConfig.usMaxPhasingTssts = (UINT16)( f_pChipOpen->ulMaxPhasingTssts & 0xFFFF ); + pSharedInfo->ChipConfig.usMaxAdpcmChannels = (UINT16)( f_pChipOpen->ulMaxAdpcmChannels & 0xFFFF ); + pSharedInfo->ChipConfig.byMaxTdmStreams = (UINT8)( f_pChipOpen->ulMaxTdmStreams & 0xFF ); + pSharedInfo->ChipConfig.fUseSynchTimestamp = (UINT8)( f_pChipOpen->fUseSynchTimestamp & 0xFF ); + for ( i = 0; i < 4; i++ ) + { + pSharedInfo->ChipConfig.ausTimestampTimeslots[ i ] = (UINT16)( f_pChipOpen->aulTimestampTimeslots[ i ] & 0xFFFF ); + pSharedInfo->ChipConfig.ausTimestampStreams[ i ] = (UINT16)( f_pChipOpen->aulTimestampStreams[ i ] & 0xFFFF ); + } + pSharedInfo->ChipConfig.byInterruptPolarity = (UINT8)( f_pChipOpen->ulInterruptPolarity & 0xFF ); + + pSharedInfo->ChipConfig.byTdmSampling = (UINT8)( f_pChipOpen->ulTdmSampling & 0xFF ); + pSharedInfo->ChipConfig.fEnableFastH100Mode = (UINT8)( f_pChipOpen->fEnableFastH100Mode & 0xFF ); + + for ( i = 0; i < cOCT6100_TDM_STREAM_MAX_GROUPS; i++ ) + { + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->ChipConfig.aulTdmStreamFreqs[ i ] = cOCT6100_TDM_STREAM_FREQ_16MHZ; + else + pSharedInfo->ChipConfig.aulTdmStreamFreqs[ i ] = f_pChipOpen->aulTdmStreamFreqs[ i ]; + } + + pSharedInfo->ChipConfig.fEnableFastH100Mode = (UINT8)( f_pChipOpen->fEnableFastH100Mode & 0xFF ); + pSharedInfo->ChipConfig.fEnableMemClkOut = (UINT8)( f_pChipOpen->fEnableMemClkOut & 0xFF ); + + /* Add 1 to the circular buffer such that all user requested events can fit in the circular queue. */ + pSharedInfo->ChipConfig.ulSoftToneEventsBufSize = f_pChipOpen->ulSoftToneEventsBufSize + 1; + pSharedInfo->ChipConfig.fEnableExtToneDetection = (UINT8)( f_pChipOpen->fEnableExtToneDetection & 0xFF ); + + if ( f_pChipOpen->ulSoftBufferPlayoutEventsBufSize != cOCT6100_INVALID_VALUE ) + pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize = f_pChipOpen->ulSoftBufferPlayoutEventsBufSize + 1; + else + pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize = 0; + pSharedInfo->ChipConfig.usMaxRemoteDebugSessions = (UINT16)( f_pChipOpen->ulMaxRemoteDebugSessions & 0xFFFF ); + + pSharedInfo->ChipConfig.fEnableChannelRecording = (UINT8)( f_pChipOpen->fEnableChannelRecording & 0xFF ); + + + + pSharedInfo->ChipConfig.fEnableProductionBist = (UINT8)( f_pChipOpen->fEnableProductionBist & 0xFF ); + pSharedInfo->ChipConfig.ulNumProductionBistLoops = f_pChipOpen->ulNumProductionBistLoops; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitializeMiscellaneousVariables + +Description: Function where all the various parameters from the API instance + are set to their defaults value. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiInitializeMiscellaneousVariables( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 i; + + /* Obtain pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Calculate the total memory available. */ + pSharedInfo->MiscVars.ulTotalMemSize = pSharedInfo->ChipConfig.ulMemoryChipSize * pSharedInfo->ChipConfig.byNumMemoryChips; + + /* Software buffers initialization. */ + + /* Tones */ + pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0; + pSharedInfo->SoftBufs.ulToneEventBufferReadPtr = 0; + pSharedInfo->SoftBufs.ulToneEventBufferSize = pSharedInfo->ChipConfig.ulSoftToneEventsBufSize; + pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt = 0; + + /* Playout */ + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr = 0; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr = 0; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferSize = pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize; + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt = 0; + + /* Set the number of conference bridges opened to zero. */ + pSharedInfo->MiscVars.usNumBridgesOpened = 0; + pSharedInfo->MiscVars.usFirstBridge = cOCT6100_INVALID_INDEX; + + /* Set the H.100 slave mode. */ + pSharedInfo->MiscVars.ulH100SlaveMode = cOCT6100_H100_TRACKA; + + /* Save the Mclk value.*/ + pSharedInfo->MiscVars.ulMclkFreq = pSharedInfo->ChipConfig.ulMemClkFreq; + + /* Init the NLP params. */ + pSharedInfo->MiscVars.usCodepoint = 0; + pSharedInfo->MiscVars.usCpuLsuWritePtr = 0; + + /* Pouch counter not present until TLVs are read. */ + pSharedInfo->DebugInfo.fPouchCounter = FALSE; + pSharedInfo->DebugInfo.fIsIsrCalledField = FALSE; + + /* Initialize the image info parameters */ + pSharedInfo->ImageInfo.fAdaptiveNoiseReduction = FALSE; + pSharedInfo->ImageInfo.fSoutNoiseBleaching = FALSE; + pSharedInfo->ImageInfo.fComfortNoise = FALSE; + pSharedInfo->ImageInfo.fBufferPlayout = TRUE; + pSharedInfo->ImageInfo.fSoutBufferPlayoutHardSkip = FALSE; + pSharedInfo->ImageInfo.fRinBufferPlayoutHardSkip = FALSE; + pSharedInfo->ImageInfo.fNlpControl = FALSE; + pSharedInfo->ImageInfo.fRinAutoLevelControl = FALSE; + pSharedInfo->ImageInfo.fSoutAutoLevelControl = FALSE; + pSharedInfo->ImageInfo.fRinHighLevelCompensation = FALSE; + pSharedInfo->ImageInfo.fSoutHighLevelCompensation = FALSE; + pSharedInfo->ImageInfo.fAlcHlcStatus = FALSE; + pSharedInfo->ImageInfo.fRinDcOffsetRemoval = FALSE; + pSharedInfo->ImageInfo.fSilenceSuppression = FALSE; + pSharedInfo->ImageInfo.fSinDcOffsetRemoval = FALSE; + pSharedInfo->ImageInfo.fToneDisabler = FALSE; + pSharedInfo->ImageInfo.fAdpcm = FALSE; + pSharedInfo->ImageInfo.fTailDisplacement = FALSE; + pSharedInfo->ImageInfo.fConferencing = FALSE; + pSharedInfo->ImageInfo.fConferencingNoiseReduction = FALSE; + pSharedInfo->ImageInfo.fDominantSpeakerEnabled = FALSE; + pSharedInfo->ImageInfo.fAecEnabled = FALSE; + pSharedInfo->ImageInfo.fAcousticEcho = FALSE; + pSharedInfo->ImageInfo.fToneRemoval = FALSE; + + pSharedInfo->ImageInfo.fDefaultErl = FALSE; + pSharedInfo->ImageInfo.fMaxEchoPoint = FALSE; + pSharedInfo->ImageInfo.fNonLinearityBehaviorA = FALSE; + pSharedInfo->ImageInfo.fNonLinearityBehaviorB = FALSE; + pSharedInfo->ImageInfo.fPerChannelTailDisplacement = FALSE; + pSharedInfo->ImageInfo.fPerChannelTailLength = FALSE; + pSharedInfo->ImageInfo.fAfTailDisplacement = FALSE; + pSharedInfo->ImageInfo.fMusicProtection = FALSE; + pSharedInfo->ImageInfo.fAftControl = FALSE; + pSharedInfo->ImageInfo.fSinVoiceDetectedStat = FALSE; + pSharedInfo->ImageInfo.fRinAppliedGainStat = FALSE; + pSharedInfo->ImageInfo.fSoutAppliedGainStat = FALSE; + pSharedInfo->ImageInfo.fListenerEnhancement = FALSE; + pSharedInfo->ImageInfo.fRoutNoiseReduction = FALSE; + pSharedInfo->ImageInfo.fAnrSnrEnhancement = FALSE; + pSharedInfo->ImageInfo.fAnrVoiceNoiseSegregation = FALSE; + pSharedInfo->ImageInfo.fRinMute = FALSE; + pSharedInfo->ImageInfo.fSinMute = FALSE; + pSharedInfo->ImageInfo.fToneDisablerVqeActivationDelay = FALSE; + pSharedInfo->ImageInfo.fAecTailLength = FALSE; + pSharedInfo->ImageInfo.fMusicProtectionConfiguration= FALSE; + pSharedInfo->ImageInfo.fBufferPlayoutSkipInEvents = FALSE; + pSharedInfo->ImageInfo.fRinEnergyStat = FALSE; + pSharedInfo->ImageInfo.fSoutEnergyStat = FALSE; + pSharedInfo->ImageInfo.fDoubleTalkBehavior = FALSE; + pSharedInfo->ImageInfo.fDoubleTalkBehaviorFieldOfst = FALSE; + pSharedInfo->ImageInfo.fIdleCodeDetection = TRUE; + pSharedInfo->ImageInfo.fIdleCodeDetectionConfiguration = FALSE; + pSharedInfo->ImageInfo.fSinLevel = TRUE; + + pSharedInfo->ImageInfo.usMaxNumberOfChannels = 0; + pSharedInfo->ImageInfo.ulToneProfileNumber = cOCT6100_INVALID_VALUE; + pSharedInfo->ImageInfo.ulBuildId = cOCT6100_INVALID_VALUE; + pSharedInfo->ImageInfo.byImageType = cOCT6100_IMAGE_TYPE_WIRELINE; + pSharedInfo->ImageInfo.usMaxTailDisplacement = 0; + pSharedInfo->ImageInfo.usMaxTailLength = cOCT6100_TAIL_LENGTH_128MS; + pSharedInfo->DebugInfo.ulDebugEventSize = 0x100; + pSharedInfo->ImageInfo.byMaxNumberPlayoutEvents = 32; + pSharedInfo->DebugInfo.ulMatrixBaseAddress = cOCT6100_MATRIX_DWORD_BASE; + pSharedInfo->DebugInfo.ulDebugChanStatsByteSize = cOCT6100_DEBUG_CHAN_STATS_EVENT_BYTE_SIZE; + pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize = cOCT6100_DEBUG_CHAN_STATS_LITE_EVENT_BYTE_SIZE; + pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress= cOCT6100_MATRIX_CHAN_SELECT_DWORD_ADD; + pSharedInfo->DebugInfo.ulMatrixTimestampBaseAddress = cOCT6100_MATRIX_TIMESTAMP_DWORD_ADD; + pSharedInfo->DebugInfo.ulMatrixWpBaseAddress = cOCT6100_MATRIX_WRITE_PTR_DWORD_ADD; + pSharedInfo->DebugInfo.ulAfWritePtrByteOffset = 206; + pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize = 4096; + pSharedInfo->DebugInfo.ulAfEventCbByteSize = 0x100000; + + /* Set all tones to invalid. */ + pSharedInfo->ImageInfo.byNumToneDetectors = 0; + for ( i = 0; i < cOCT6100_MAX_TONE_EVENT; i++ ) + { + pSharedInfo->ImageInfo.aToneInfo[ i ].ulToneID = cOCT6100_INVALID_VALUE; + pSharedInfo->ImageInfo.aToneInfo[ i ].ulDetectionPort = cOCT6100_INVALID_PORT; + Oct6100UserMemSet( pSharedInfo->ImageInfo.aToneInfo[ i ].aszToneName, 0x00, cOCT6100_TLV_MAX_TONE_NAME_SIZE ); + } + /* Initialize the channel recording info. */ + pSharedInfo->DebugInfo.usRecordChanIndex = pSharedInfo->ChipConfig.usMaxChannels; + pSharedInfo->DebugInfo.usRecordMemIndex = cOCT6100_INVALID_INDEX; + + pSharedInfo->DebugInfo.usCurrentDebugChanIndex = cOCT6100_INVALID_INDEX; + /* Initialize the mixer information. */ + pSharedInfo->MixerInfo.usFirstBridgeEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastBridgeEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = cOCT6100_INVALID_INDEX; + + pSharedInfo->MixerInfo.usRecordCopyEventIndex = cOCT6100_INVALID_INDEX; + pSharedInfo->MixerInfo.usRecordSinEventIndex = cOCT6100_INVALID_INDEX; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCalculateInstanceSizes + +Description: Calculates the amount of memory needed for the instance + structure memory block based on the user's configuration. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pChipOpen Pointer to user chip configuration structure. + +f_pInstSizes Pointer to structure containing the size of memory needed + by all pointers internal to the API instance. The memory + is needed to keep track of the present state of all the + chip's resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiCalculateInstanceSizes( + IN OUT tPOCT6100_CHIP_OPEN f_pChipOpen, + OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + UINT32 ulApiInstProcessSpecific; + UINT32 ulTempVar; + UINT32 ulResult; + + /* Start with all instance sizes set to 0. */ + Oct6100UserMemSet( f_pInstSizes, 0x00, sizeof( tOCT6100_API_INSTANCE_SIZES ) ); + + /* All memory sizes are rounded up to the next multiple of 64 bytes. */ + + /*-----------------------------------------------------------------------------*/ + /* Obtain size of static members of API instance. */ + f_pInstSizes->ulApiInstStatic = sizeof( tOCT6100_SHARED_INFO ); + mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulApiInstStatic, ulTempVar ) + + /* Calculate memory needed by pointers internal to the API instance. */ + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the EC channels. */ + ulResult = Oct6100ApiGetChannelsEchoSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Memory needed by the TSI structures. */ + ulResult = Oct6100ApiGetTsiCnctSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the conference bridges. */ + ulResult = Oct6100ApiGetConfBridgeSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Memory needed by the buffer playout structures. */ + ulResult = Oct6100ApiGetPlayoutBufferSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + + + /*-----------------------------------------------------------------------------*/ + /* Memory needed by soft Rx Event buffers. */ + ulResult = Oct6100ApiGetEventsSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for phasing tssts. */ + ulResult = Oct6100ApiGetPhasingTsstSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the ADPCM channels. */ + ulResult = Oct6100ApiGetAdpcmChanSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the management of TSSTs. */ + ulResult = Oct6100ApiGetTsstSwSizes( f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate memory needed for the management of the mixer. */ + ulResult = Oct6100ApiGetMixerSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Determine amount of memory needed for memory allocation softwares. These + pieces of software will be responsible for the allocation of the chip's + external memory and API memory. */ + ulResult = Oct6100ApiGetMemorySwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Memory needed for remote debugging sessions. */ + ulResult = Oct6100ApiGetRemoteDebugSwSizes( f_pChipOpen, f_pInstSizes ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Calculate total memory needed by pointers internal to API instance. The + total contains both the process specific portion of the instance + (tOCT6100_INSTANCE_API) and the shared portion (tOCT6100_SHARED_INFO). The + process specific portion will be used only in the case where the host system + is a single-process one. */ + + ulApiInstProcessSpecific = sizeof( tOCT6100_INSTANCE_API ); + mOCT6100_ROUND_MEMORY_SIZE( ulApiInstProcessSpecific, ulTempVar ) + + f_pInstSizes->ulApiInstTotal = + f_pInstSizes->ulChannelList + + f_pInstSizes->ulChannelAlloc + + f_pInstSizes->ulTsiCnctList + + f_pInstSizes->ulTsiCnctAlloc + + f_pInstSizes->ulSoftToneEventsBuffer + + f_pInstSizes->ulSoftBufPlayoutEventsBuffer + + f_pInstSizes->ulBiDirChannelList + + f_pInstSizes->ulBiDirChannelAlloc + + f_pInstSizes->ulConfBridgeList + + f_pInstSizes->ulConfBridgeAlloc + + f_pInstSizes->ulFlexConfParticipantsList + + f_pInstSizes->ulFlexConfParticipantsAlloc + + f_pInstSizes->ulPlayoutBufList + + f_pInstSizes->ulPlayoutBufAlloc + + f_pInstSizes->ulPlayoutBufMemoryNodeList + + + f_pInstSizes->ulCopyEventList + + f_pInstSizes->ulCopyEventAlloc + + f_pInstSizes->ulMixerEventList + + f_pInstSizes->ulMixerEventAlloc + + f_pInstSizes->ulPhasingTsstList + + f_pInstSizes->ulPhasingTsstAlloc + + f_pInstSizes->ulAdpcmChannelList + + f_pInstSizes->ulAdpcmChannelAlloc + + f_pInstSizes->ulConversionMemoryAlloc + + f_pInstSizes->ulTsiMemoryAlloc + + f_pInstSizes->ulRemoteDebugList + + f_pInstSizes->ulRemoteDebugTree + + f_pInstSizes->ulRemoteDebugPktCache + + f_pInstSizes->ulRemoteDebugDataBuf + + f_pInstSizes->ulTsstEntryList + + f_pInstSizes->ulTsstEntryAlloc + + f_pInstSizes->ulTsstAlloc + + f_pInstSizes->ulApiInstStatic + + ulApiInstProcessSpecific; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiAllocateInstanceMemory + +Description: Allocates the API instance memory to the various members of + the structure f_pApiInstance according to the sizes contained + in f_pInstSizes. No initialization of this memory is + performed. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_pInstSizes Pointer to structure containing the size of memory needed + by all pointers internal to the API instance. The memory + is needed to keep track of the present state of all the + chip's resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiAllocateInstanceMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_API_INSTANCE_SIZES f_pInstSizes ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulOffset; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get address of first UINT32 of memory in API instance structure following */ + /* the static members of the API instance structure. */ + ulOffset = f_pInstSizes->ulApiInstStatic; + + /*===================================================================*/ + /* Allocate memory for the echo channels.*/ + pSharedInfo->ulChannelListOfst = ulOffset; + ulOffset += f_pInstSizes->ulChannelList; + pSharedInfo->ulChannelAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulChannelAlloc; + + /*===================================================================*/ + /* Allocate memory for the TSI connections */ + pSharedInfo->ulTsiCnctListOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsiCnctList; + pSharedInfo->ulTsiCnctAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsiCnctAlloc; + pSharedInfo->ulMixerEventListOfst = ulOffset; + ulOffset += f_pInstSizes->ulMixerEventList; + pSharedInfo->ulMixerEventAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulMixerEventAlloc; + + pSharedInfo->ulBiDirChannelListOfst = ulOffset; + ulOffset += f_pInstSizes->ulBiDirChannelList; + pSharedInfo->ulBiDirChannelAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulBiDirChannelAlloc; + pSharedInfo->ulCopyEventListOfst = ulOffset; + ulOffset += f_pInstSizes->ulCopyEventList; + pSharedInfo->ulCopyEventAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulCopyEventAlloc; + + /*===================================================================*/ + /* Allocate memory for the conference bridges */ + pSharedInfo->ulConfBridgeListOfst = ulOffset; + ulOffset += f_pInstSizes->ulConfBridgeList; + pSharedInfo->ulConfBridgeAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulConfBridgeAlloc; + + /*===================================================================*/ + /* Allocate memory for the flexible conferencing participants. */ + pSharedInfo->ulFlexConfParticipantListOfst = ulOffset; + ulOffset += f_pInstSizes->ulFlexConfParticipantsList; + pSharedInfo->ulFlexConfParticipantAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulFlexConfParticipantsAlloc; + + /*===================================================================*/ + /* Allocate memory for the play-out buffers */ + pSharedInfo->ulPlayoutBufListOfst = ulOffset; + ulOffset += f_pInstSizes->ulPlayoutBufList; + pSharedInfo->ulPlayoutBufAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulPlayoutBufAlloc; + pSharedInfo->ulPlayoutBufMemoryNodeListOfst = ulOffset; + ulOffset += f_pInstSizes->ulPlayoutBufMemoryNodeList; + + + + /*===================================================================*/ + /* Allocate memory for the phasing TSSTs */ + pSharedInfo->ulPhasingTsstListOfst = ulOffset; + ulOffset += f_pInstSizes->ulPhasingTsstList; + pSharedInfo->ulPhasingTsstAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulPhasingTsstAlloc; + + /*===================================================================*/ + /* Allocate memory for the ADPCM channel */ + pSharedInfo->ulAdpcmChanAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulAdpcmChannelAlloc; + pSharedInfo->ulAdpcmChanListOfst = ulOffset; + ulOffset += f_pInstSizes->ulAdpcmChannelList; + + /*===================================================================*/ + /* Allocate memory for the conversion memory */ + pSharedInfo->ulConversionMemoryAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulConversionMemoryAlloc; + + /*===================================================================*/ + /* Allocate memory for the TSI chariot memory */ + pSharedInfo->ulTsiMemoryAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsiMemoryAlloc; + + /*===================================================================*/ + /* Allocate memory for the TSST management */ + pSharedInfo->ulTsstAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsstAlloc; + pSharedInfo->ulTsstListOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsstEntryList; + pSharedInfo->ulTsstListAllocOfst = ulOffset; + ulOffset += f_pInstSizes->ulTsstEntryAlloc; + + /*===================================================================*/ + pSharedInfo->SoftBufs.ulToneEventBufferMemOfst = ulOffset; + ulOffset += f_pInstSizes->ulSoftToneEventsBuffer; + + pSharedInfo->SoftBufs.ulBufPlayoutEventBufferMemOfst = ulOffset; + ulOffset += f_pInstSizes->ulSoftBufPlayoutEventsBuffer; + /*===================================================================*/ + pSharedInfo->RemoteDebugInfo.ulSessionListOfst = ulOffset; + ulOffset += f_pInstSizes->ulRemoteDebugList; + + pSharedInfo->RemoteDebugInfo.ulSessionTreeOfst = ulOffset; + ulOffset += f_pInstSizes->ulRemoteDebugTree; + + pSharedInfo->RemoteDebugInfo.ulDataBufOfst = ulOffset; + ulOffset += f_pInstSizes->ulRemoteDebugDataBuf; + + pSharedInfo->RemoteDebugInfo.ulPktCacheOfst = ulOffset; + ulOffset += f_pInstSizes->ulRemoteDebugPktCache; + /*===================================================================*/ + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitializeInstanceMemory + +Description: Initializes the various members of the structure f_pApiInstance + to reflect the current state of the chip and its resources. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiInitializeInstanceMemory( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + UINT32 ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize API EC channels. */ + ulResult = Oct6100ApiChannelsEchoSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the API TSI connection structures. */ + ulResult = Oct6100ApiTsiCnctSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the API conference bridges. */ + ulResult = Oct6100ApiConfBridgeSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the API buffer playout structures. */ + ulResult = Oct6100ApiPlayoutBufferSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the API phasing tssts. */ + ulResult = Oct6100ApiPhasingTsstSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the API ADPCM channels. */ + ulResult = Oct6100ApiAdpcmChanSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the external memory management structures. */ + ulResult = Oct6100ApiMemorySwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize TSST management stuctures. */ + ulResult = Oct6100ApiTsstSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the mixer management stuctures. */ + ulResult = Oct6100ApiMixerSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Initialize the remote debugging session management variables. */ + ulResult = Oct6100ApiRemoteDebuggingSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*-----------------------------------------------------------------------------*/ + /* Configure the interrupt registers. */ + ulResult = Oct6100ApiIsrSwInit( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGetChipRevisionNum + +Description: Reads the chip's revision number register. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiGetChipRevisionNum( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 usReadData; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get the chip revision number. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.ulReadAddress = cOCT6100_CHIP_ID_REVISION_REG; + ReadParams.pusReadData = &usReadData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Save the info in the API miscellaneous structure. */ + pSharedInfo->MiscVars.usChipId = (UINT16)( usReadData & 0xFF ); + pSharedInfo->MiscVars.usChipRevision = (UINT16)( usReadData >> 8 ); + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiDecodeKeyAndBist + +Description: This function decodes the key and runs the automatic BIST. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiDecodeKeyAndBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT16 ausBistData[ 3 ]; + UINT16 usReadData; + UINT32 ulResult; + BOOL fBitEqual; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain a local pointer to the chip config structure */ + /* contained in the instance structure. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* Set the process context and user chip ID parameters once and for all. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* Write key in CPU internal memory. */ + for(i=0; i<8; i++) + { + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = 0x0000; + if (( i % 2 ) == 0) + { + WriteParams.usWriteData |= ((UINT16)pChipConfig->pbyImageFile[0x100 + ((i/2)*4) + 2]) << 8; + WriteParams.usWriteData |= ((UINT16)pChipConfig->pbyImageFile[0x100 + ((i/2)*4) + 3]) << 0; + } + else + { + WriteParams.usWriteData |= ((UINT16)pChipConfig->pbyImageFile[0x100 + ((i/2)*4) + 0]) << 8; + WriteParams.usWriteData |= ((UINT16)pChipConfig->pbyImageFile[0x100 + ((i/2)*4) + 1]) << 0; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x152; + WriteParams.usWriteData = (UINT16)( 0x8000 | i ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Write one in CPU internal memory. */ + for(i=0; i<8; i++) + { + WriteParams.ulWriteAddress = 0x150; + if (i == 0) + { + WriteParams.usWriteData = 0x0001; + } + else + { + WriteParams.usWriteData = 0x0000; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x152; + WriteParams.usWriteData = (UINT16)( 0x8000 | ( i + 8 )); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Clear memory access registers: */ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x152; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Run BISTs and key decode. */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0081; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for the key decode PC to clear. */ + ulResult = Oct6100ApiWaitForPcRegisterBit( f_pApiInstance, 0x160, 0, 0, 100000, &fBitEqual ); + if ( TRUE != fBitEqual ) + return cOCT6100_ERR_FATAL_13; + + /* Read the key valid bit to make sure everything is ok. */ + ReadParams.ulReadAddress = 0x160; + ReadParams.pusReadData = &usReadData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Either the firmware image was not loaded correctly (from pointer given by user) */ + /* or the channel capacity pins of the chip do not match what the firmware is expecting. */ + if ( ( usReadData & 0x4 ) == 0 ) + return cOCT6100_ERR_OPEN_INVALID_FIRMWARE_OR_CAPACITY_PINS; + + /* Read the result of the internal memory bist. */ + ReadParams.ulReadAddress = 0x110; + ReadParams.pusReadData = &ausBistData[ 0 ]; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ReadParams.ulReadAddress = 0x114; + ReadParams.pusReadData = &ausBistData[ 1 ]; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ReadParams.ulReadAddress = 0x118; + ReadParams.pusReadData = &ausBistData[ 2 ]; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if an error was reported. */ + if (ausBistData[0] != 0x0000 || ausBistData[1] != 0x0000 || ausBistData[2] != 0x0000) + return cOCT6100_ERR_OPEN_INTERNAL_MEMORY_BIST; + + /* Put key decoder in powerdown. */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x008A; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBootFc2Pll + +Description: Configures the chip's FC2 PLL. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiBootFc2Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + UINT32 ulFc2PllDivisor = 0; + UINT32 ulMtDivisor = 0; + UINT32 ulFcDivisor = 0; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to chip configuration structure. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* First put the chip and main registers in soft-reset. */ + WriteParams.ulWriteAddress = 0x100; + WriteParams.usWriteData = 0x0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select register configuration based on the memory frequency. */ + switch ( f_pApiInstance->pSharedInfo->ChipConfig.ulMemClkFreq ) + { + case 133000000: + ulFc2PllDivisor = 0x1050; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 672; + pSharedInfo->MiscVars.usMaxH100Speed = 124; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x050B; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0516; + + break; + case 125000000: + ulFc2PllDivisor = 0x0F50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 624; + pSharedInfo->MiscVars.usMaxH100Speed = 116; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x04CA; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x04D4; + + break; + case 117000000: + ulFc2PllDivisor = 0x0E50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 576; + pSharedInfo->MiscVars.usMaxH100Speed = 108; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0489; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0492; + + break; + case 108000000: + ulFc2PllDivisor = 0x0D50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 528; + pSharedInfo->MiscVars.usMaxH100Speed = 99; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0408; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0410; + + break; + case 100000000: + ulFc2PllDivisor = 0x0C50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 480; + pSharedInfo->MiscVars.usMaxH100Speed = 91; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x03C8; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x03D0; + + break; + case 92000000: + ulFc2PllDivisor = 0x0B50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 432; + pSharedInfo->MiscVars.usMaxH100Speed = 83; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0387; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x038E; + + break; + case 83000000: + ulFc2PllDivisor = 0x0A50; + ulMtDivisor = 0x4300; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 384; + pSharedInfo->MiscVars.usMaxH100Speed = 74; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0346; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x034C; + + break; + case 75000000: + ulFc2PllDivisor = 0x0950; + ulMtDivisor = 0x4200; + ulFcDivisor = 0x4043; + pSharedInfo->MiscVars.usMaxNumberOfChannels = 336; + pSharedInfo->MiscVars.usMaxH100Speed = 64; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + pSharedInfo->MiscVars.usTdmClkBoundary = 0x0306; + else + pSharedInfo->MiscVars.usTdmClkBoundary = 0x030C; + + break; + default: + return cOCT6100_ERR_FATAL_DB; + } + + /* Verify that the max channel is not too big based on the chip frequency. */ + if ( pSharedInfo->ChipConfig.usMaxChannels > pSharedInfo->MiscVars.usMaxNumberOfChannels ) + return cOCT6100_ERR_OPEN_MAX_ECHO_CHANNELS; + + /* Setup delay chains. */ + if ( (pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR) || (pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + /* SDRAM */ + WriteParams.ulWriteAddress = 0x1B0; + WriteParams.usWriteData = 0x1003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B2; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B4; + WriteParams.usWriteData = 0x4030; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B6; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* if ( cOCT6100_MEM_TYPE_DDR == pChipConfig->byMemoryType ) */ + { + /* DDR */ + WriteParams.ulWriteAddress = 0x1B0; + WriteParams.usWriteData = 0x201F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B2; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B4; + WriteParams.usWriteData = 0x1000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1B6; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* udqs */ + WriteParams.ulWriteAddress = 0x1B8; + WriteParams.usWriteData = 0x1003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1BA; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* ldqs */ + WriteParams.ulWriteAddress = 0x1BC; + WriteParams.usWriteData = 0x1000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x1BE; + WriteParams.usWriteData = 0x0021; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x12C; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x12E; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select fc2pll for fast_clk and mtsclk sources. Select mem_clk_i for afclk. */ + WriteParams.ulWriteAddress = 0x140; + WriteParams.usWriteData = (UINT16)ulMtDivisor; + + if ( f_pApiInstance->pSharedInfo->ChipConfig.byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + WriteParams.usWriteData |= 0x0001; + else + WriteParams.usWriteData |= 0x0004; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x144; + WriteParams.usWriteData = (UINT16)ulFcDivisor; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x13E; + WriteParams.usWriteData = 0x0001; /* Remove reset from above divisors */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select upclk directly as ref source for fc2pll. */ + WriteParams.ulWriteAddress = 0x134; + if ( pChipConfig->ulUpclkFreq == cOCT6100_UPCLK_FREQ_66_67_MHZ ) + { + WriteParams.usWriteData = 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Remove the reset */ + WriteParams.usWriteData = 0x0102; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + else /* pChipConfig->ulUpclkFreq == cOCT6100_UPCLK_FREQ_33_33_MHZ */ + { + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Setup fc2pll. */ + WriteParams.ulWriteAddress = 0x132; + WriteParams.usWriteData = (UINT16)ulFc2PllDivisor; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.usWriteData |= 0x02; /* Raise fb divisor reset. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.usWriteData |= 0x80; /* Raise IDDTN signal.*/ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for fc2pll to stabilize. */ + aulWaitTime[ 0 ] = 2000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Drive mem_clk_o out on proper interface. */ + if ( TRUE == pChipConfig->fEnableMemClkOut ) + { + if ( (pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR) || (pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + WriteParams.ulWriteAddress = 0x128; + WriteParams.usWriteData = 0x0301; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_DDR || pChipConfig->byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + { + WriteParams.ulWriteAddress = 0x12A; + WriteParams.usWriteData = 0x000F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProgramFc1Pll + +Description: Configures the chip's FC1 PLL. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiProgramFc1Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to chip configuration structure. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* Programm P/Z bits. */ + WriteParams.ulWriteAddress = 0x130; + + if ( f_pApiInstance->pSharedInfo->ChipConfig.byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS ) + WriteParams.usWriteData = 0x0041; + else + WriteParams.usWriteData = 0x0040; + + WriteParams.usWriteData |= ( pChipConfig->byMemoryType << 8 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Raise FB divisor. */ + WriteParams.usWriteData |= 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Raise IDDTN. */ + WriteParams.usWriteData |= 0x0080; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for fc1pll to stabilize. */ + aulWaitTime[ 0 ] = 2000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable all the clock domains to do reset procedure. */ + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x015F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + aulWaitTime[ 0 ] = 15000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBootFc1Pll + +Description: Boot the chip's FC1 PLL. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiBootFc1Pll( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 aulWaitTime[ 2 ]; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Obtain local pointer to chip configuration structure. */ + pChipConfig = &pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pChipConfig->ulUserChipId; + + /* Force bist_clk also (it too is used on resetable flops). */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0188; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Force all cpu clocks on chariot controllers. */ + WriteParams.ulWriteAddress = 0x182; + WriteParams.usWriteData = 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x184; + WriteParams.usWriteData = 0x0202; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + aulWaitTime[ 0 ] = 1000; + aulWaitTime[ 1 ] = 0; + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Remove the reset on the entire chip and disable CPU access caching. */ + WriteParams.ulWriteAddress = 0x100; + WriteParams.usWriteData = 0x2003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Remove the bist_clk. It is no longer needed.*/ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0088; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Disable all clks to prepare for bist clock switchover. */ + WriteParams.ulWriteAddress = 0x182; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x184; + WriteParams.usWriteData = 0x0101; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Deassert bist_active */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0008; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Change CPU interface to normal mode (from boot mode). */ + WriteParams.ulWriteAddress = 0x154; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Give a couple of BIST clock cycles to turn off the BIST permanently. */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0108; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWaitForTime( f_pApiInstance, aulWaitTime ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Turn BIST clock off for the last time. */ + WriteParams.ulWriteAddress = 0x160; + WriteParams.usWriteData = 0x0008; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Reset procedure done! */ + + /* Enable mclk for cpu interface and external memory controller. */ + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x0100; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiLoadImage + +Description: This function writes the firmware image in the external memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiLoadImage( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_BURST_PARAMS BurstParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT32 ulTempPtr; + UINT32 ulNumWrites; + PUINT16 pusSuperArray; + PUINT8 pbyImageFile; + UINT32 ulByteCount = 0; + UINT16 usReadData; + UINT32 ulAddressOfst; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Breakdown image into subcomponents. */ + ulTempPtr = cOCT6100_IMAGE_FILE_BASE + cOCT6100_IMAGE_AF_CST_OFFSET; + + for(i=0;iImageRegion[ i ].ulPart1Size = pSharedInfo->ChipConfig.pbyImageFile[ 0x110 + ( i * 4 ) + 0 ]; + pSharedInfo->ImageRegion[ i ].ulPart2Size = pSharedInfo->ChipConfig.pbyImageFile[ 0x110 + ( i * 4 ) + 1 ]; + pSharedInfo->ImageRegion[ i ].ulClockInfo = pSharedInfo->ChipConfig.pbyImageFile[ 0x110 + ( i * 4 ) + 2 ]; + pSharedInfo->ImageRegion[ i ].ulReserved = pSharedInfo->ChipConfig.pbyImageFile[ 0x110 + ( i * 4 ) + 3 ]; + + if (i == 0) /* AF constant. */ + { + pSharedInfo->ImageRegion[ i ].ulPart1BaseAddress = ulTempPtr & 0x07FFFFFF; + pSharedInfo->ImageRegion[ i ].ulPart2BaseAddress = 0; + + ulTempPtr += ( pSharedInfo->ImageRegion[ i ].ulPart1Size * 612 ); + } + else if (i == 1) /* NLP image */ + { + pSharedInfo->ImageRegion[ i ].ulPart1BaseAddress = ulTempPtr & 0x07FFFFFF; + pSharedInfo->ImageRegion[ i ].ulPart2BaseAddress = 0; + + ulTempPtr += ( pSharedInfo->ImageRegion[ i ].ulPart1Size * 2056 ); + } + else /* Others */ + { + pSharedInfo->ImageRegion[ i ].ulPart1BaseAddress = ulTempPtr & 0x07FFFFFF; + ulTempPtr += ( pSharedInfo->ImageRegion[ i ].ulPart1Size * 2064 ); + + pSharedInfo->ImageRegion[ i ].ulPart2BaseAddress = ulTempPtr & 0x07FFFFFF; + ulTempPtr += ( pSharedInfo->ImageRegion[ i ].ulPart2Size * 2448 ); + } + } + + /* Write the image in external memory. */ + ulNumWrites = pSharedInfo->ChipConfig.ulImageSize / 2; + + BurstParams.ulWriteAddress = cOCT6100_IMAGE_FILE_BASE; + BurstParams.pusWriteData = pSharedInfo->MiscVars.ausSuperArray; + + pusSuperArray = pSharedInfo->MiscVars.ausSuperArray; + pbyImageFile = pSharedInfo->ChipConfig.pbyImageFile; + + while ( ulNumWrites != 0 ) + { + if ( ulNumWrites >= pSharedInfo->ChipConfig.usMaxRwAccesses ) + BurstParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + else + BurstParams.ulWriteLength = ulNumWrites; + + for ( i = 0; i < BurstParams.ulWriteLength; i++ ) + { + pusSuperArray[ i ] = ( UINT16 )(( pbyImageFile [ ulByteCount++ ]) << 8); + pusSuperArray[ i ] |= ( UINT16 )pbyImageFile [ ulByteCount++ ]; + } + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + BurstParams.ulWriteAddress += 2 * BurstParams.ulWriteLength; + ulNumWrites -= BurstParams.ulWriteLength; + } + + /* Perform a serie of reads to make sure the image was correclty written into memory. */ + ulAddressOfst = ( pSharedInfo->ChipConfig.ulImageSize / 2 ) & 0xFFFFFFFE; + while ( ulAddressOfst != 0 ) + { + ReadParams.ulReadAddress = cOCT6100_IMAGE_FILE_BASE + ulAddressOfst; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( (usReadData >> 8) != pbyImageFile[ ulAddressOfst ] ) + return cOCT6100_ERR_OPEN_IMAGE_WRITE_FAILED; + + ulAddressOfst = (ulAddressOfst / 2) & 0xFFFFFFFE; + } + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCpuRegisterBist + +Description: Tests the operation of the CPU registers. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiCpuRegisterBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 i; + UINT16 usReadData; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Assign read data pointer that will be used throughout the function. */ + ReadParams.pusReadData = &usReadData; + + /* Start with a walking bit test. */ + for ( i = 0; i < 16; i ++ ) + { + /* Write at address 0x150.*/ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = (UINT16)( 0x1 << i ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write at address 0x180.*/ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = (UINT16)( 0x1 << ( 15 - i ) ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read back the two registers to make sure the acceses were successfull. */ + ReadParams.ulReadAddress = 0x150; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != ( 0x1 << i ) ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + ReadParams.ulReadAddress = 0x180; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != ( 0x1 << ( 15 - i ) ) ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + } + + /* Write at address 0x150. */ + WriteParams.ulWriteAddress = 0x150; + WriteParams.usWriteData = 0xCAFE; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write at address 0x180. */ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = 0xDECA; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read back the two registers to make sure the acceses were successfull. */ + ReadParams.ulReadAddress = 0x150; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xCAFE ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + ReadParams.ulReadAddress = 0x180; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != 0xDECA ) + return cOCT6100_ERR_OPEN_CPU_REG_BIST_ERROR; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiBootSdram + +Description: Configure and test the SDRAM. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiBootSdram( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT16 usReadData; + UINT16 usWriteData23E; + UINT16 usWriteData230; + UINT32 i; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get local pointer to the chip configuration structure.*/ + pChipConfig = &f_pApiInstance->pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + usWriteData23E = 0x0000; + usWriteData230 = 0x0000; + + if ( (pSharedInfo->ChipConfig.byMemoryType == cOCT6100_MEM_TYPE_SDR) || (pSharedInfo->ChipConfig.byMemoryType == cOCT6100_MEM_TYPE_SDR_PLL_BYPASS) ) + { + /* SDRAM: */ + switch( pChipConfig->ulMemoryChipSize ) + { + case cOCT6100_MEMORY_CHIP_SIZE_8MB: + usWriteData230 |= ( cOCT6100_16MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_16MB: + usWriteData230 |= ( cOCT6100_32MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_32MB: + usWriteData230 |= ( cOCT6100_64MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_64MB: + usWriteData230 |= ( cOCT6100_128MB_MEMORY_BANKS << 2 ); + break; + default: + return cOCT6100_ERR_FATAL_16; + } + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Precharge all banks. */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0010; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Program the mode register. */ + usWriteData23E = 0x0030; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0000; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Do CBR refresh (twice) */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0040; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + else + { + /* DDR: */ + switch( pChipConfig->ulMemoryChipSize ) + { + case cOCT6100_MEMORY_CHIP_SIZE_16MB: + usWriteData230 |= ( cOCT6100_16MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_32MB: + usWriteData230 |= ( cOCT6100_32MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_64MB: + usWriteData230 |= ( cOCT6100_64MB_MEMORY_BANKS << 2 ); + break; + case cOCT6100_MEMORY_CHIP_SIZE_128MB: + usWriteData230 |= ( cOCT6100_128MB_MEMORY_BANKS << 2 ); + break; + default: + return cOCT6100_ERR_FATAL_17; + } + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Precharge all banks. */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0010; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Program DDR mode register. */ + usWriteData23E = 0x4000; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0000; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Program SDR mode register. */ + usWriteData23E = 0x0161; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0000; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Precharge all banks. */ + usWriteData23E = 0xFFFF; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0010; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Do CBR refresh (twice) */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0040; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle.*/ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Program SDR mode register. */ + usWriteData23E = 0x0061; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0000; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + usWriteData230 |= 0x0002; + + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x23E; + WriteParams.usWriteData = usWriteData23E; + for ( i = 0; i < 5; i++ ) + { + /* Wait cycle. */ + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Set the refresh frequency. */ + WriteParams.ulWriteAddress = 0x242; + WriteParams.usWriteData = 0x0400; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x244; + WriteParams.usWriteData = 0x0200; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x248; + WriteParams.usWriteData = 0x800; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x246; + WriteParams.usWriteData = 0x0012; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable the SDRAM and refreshes. */ + usWriteData230 &= 0x000C; + usWriteData230 |= 0x0001; + + WriteParams.ulWriteAddress = 0x230; + WriteParams.usWriteData = usWriteData230; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x246; + WriteParams.usWriteData = 0x0013; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiEnableClocks + +Description: This function will disable clock masking for all the modules + of the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiEnableClocks( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Initialize the process context and user chip ID once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Enable tdmie / adpcm mclk clocks. */ + WriteParams.ulWriteAddress = 0x186; + WriteParams.usWriteData = 0x015F; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the DQS register for the DDR memory */ + WriteParams.ulWriteAddress = 0x180; + WriteParams.usWriteData = 0xFF00; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable pgsp chariot clocks */ + WriteParams.ulWriteAddress = 0x182; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable af/mt chariot clocks */ + WriteParams.ulWriteAddress = 0x184; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProgramNLP + +Description: This function will write image values to configure the NLP. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiProgramNLP( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + UINT32 ulResult; + UINT16 usReadData; + UINT16 usReadHighData; + BOOL fBitEqual; + UINT32 ulEgoEntry[4]; + UINT32 ulTempAddress; + UINT32 ulAfCpuUp = FALSE; + UINT32 i; + UINT32 ulLoopCounter = 0; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get local pointer to the chip configuration structure.*/ + pChipConfig = &f_pApiInstance->pSharedInfo->ChipConfig; + + /* Initialize the process context and user chip ID once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Initialize the process context and user chip ID once and for all. */ + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + if ( pSharedInfo->ChipConfig.fEnableProductionBist == TRUE ) + { + UINT32 ulReadData; + UINT32 ulBitPattern; + UINT32 j, k; + + /* Since the pouch section (256 bytes) will not be tested by the firmware, */ + /* the API has to make sure this section is working correctly. */ + for ( k = 0; k < 2; k ++ ) + { + if ( k == 0 ) + ulBitPattern = 0x1; + else + ulBitPattern = 0xFFFFFFFE; + + for ( j = 0; j < 32; j ++ ) + { + /* Write the DWORDs. */ + for ( i = 0; i < 64; i ++ ) + { + ulResult = Oct6100ApiWriteDword( f_pApiInstance, cOCT6100_POUCH_BASE + i * 4, ulBitPattern << j ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Read the DWORDs. */ + for ( i = 0; i < 64; i ++ ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, cOCT6100_POUCH_BASE + i * 4, &ulReadData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the value matches. */ + if ( ( ulBitPattern << j ) != ulReadData ) + return cOCT6100_ERR_OPEN_PRODUCTION_BIST_POUCH_ERROR; + } + } + } + } + + /* Write the image info in the chip. */ + WriteParams.ulWriteAddress = cOCT6100_PART1_END_STATICS_BASE; + WriteParams.usWriteData = (UINT16)( ( pSharedInfo->ImageRegion[ 0 ].ulPart1BaseAddress >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pSharedInfo->ImageRegion[ 0 ].ulPart1BaseAddress & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for( i = 0; i < 8; i++ ) + { + if ( pSharedInfo->ImageRegion[ i + 2 ].ulPart1Size != 0 ) + { + WriteParams.ulWriteAddress = cOCT6100_PART1_END_STATICS_BASE + 0x4 + ( i * 0xC ); + WriteParams.usWriteData = (UINT16)(( pSharedInfo->ImageRegion[ i + 2 ].ulPart1BaseAddress >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pSharedInfo->ImageRegion[ i + 2 ].ulPart1BaseAddress & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + if ( pSharedInfo->ImageRegion[ i + 2 ].ulPart2Size != 0 ) + { + WriteParams.ulWriteAddress = cOCT6100_PART1_END_STATICS_BASE + 0x4 + ( i * 0xC ) + 4; + WriteParams.usWriteData = (UINT16)(( pSharedInfo->ImageRegion[ i + 2 ].ulPart2BaseAddress >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( pSharedInfo->ImageRegion[ i + 2 ].ulPart2BaseAddress & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + WriteParams.ulWriteAddress = cOCT6100_PART1_END_STATICS_BASE + 0x4 + ( i * 0xC ) + 8; + WriteParams.usWriteData = 0x0000; + WriteParams.usWriteData |= ( pSharedInfo->ImageRegion[ i + 2 ].ulPart1Size << 8 ); + WriteParams.usWriteData |= pSharedInfo->ImageRegion[ i + 2 ].ulPart2Size; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = 0x0000; + WriteParams.usWriteData |= ( pSharedInfo->ImageRegion[ i + 2 ].ulClockInfo << 8 ); + WriteParams.usWriteData |= pSharedInfo->ImageRegion[ i + 2 ].ulReserved; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Put NLP in config mode. */ + WriteParams.ulWriteAddress = 0x2C2; + WriteParams.usWriteData = 0x160E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x692; + WriteParams.usWriteData = 0x010A; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Upload the up to 8 NLP pages + 1 AF page (for timing reasons). */ + for ( i = 0; i < pSharedInfo->ImageRegion[ 1 ].ulPart1Size; i++ ) + { + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 1 ].ulPart1BaseAddress + 1028 * ( i * 2 ), 0x1280, 1024, &(ulEgoEntry[0])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 1 ].ulPart1BaseAddress + 1028 * (( i * 2 ) + 1 ), 0x1680, 1024, &(ulEgoEntry[2])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiRunEgo( f_pApiInstance, FALSE, 2, ulEgoEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Shift mt chariot memories. This process will complete by the time */ + /* the next LSU transfer is done. */ + WriteParams.ulWriteAddress = 0x692; + WriteParams.usWriteData = 0x010B; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiWaitForPcRegisterBit( f_pApiInstance, 0x692, 0, 0, 100000, &fBitEqual ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + if ( TRUE != fBitEqual ) + return cOCT6100_ERR_FATAL_1A; + } + + /* 1 AF page (for timing reasons). */ + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 2 ].ulPart1BaseAddress + (516 * 0), 0x1280, 512, &(ulEgoEntry[0])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 2 ].ulPart1BaseAddress + (516 * 1), 0x1480, 512, &(ulEgoEntry[2])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiRunEgo( f_pApiInstance, FALSE, 2, ulEgoEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 2 ].ulPart1BaseAddress + (516 * 2), 0x1680, 512, &(ulEgoEntry[0])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiCreateEgoEntry( cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + pSharedInfo->ImageRegion[ 2 ].ulPart1BaseAddress + (516 * 3), 0x1880, 512, &(ulEgoEntry[2])); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiRunEgo( f_pApiInstance, FALSE, 2, ulEgoEntry ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write constant memory init context position in channel "672" for pgsp. */ + WriteParams.ulWriteAddress = 0x71A; + WriteParams.usWriteData = 0x8000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set fixed PGSP event_in base address to 800 on a 2k boundary */ + WriteParams.ulWriteAddress = 0x716; + WriteParams.usWriteData = 0x800 >> 11; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set fixed PGSP event_out to 0x2C0000h on a 16k boundary */ + WriteParams.ulWriteAddress = 0x71C; + WriteParams.usWriteData = 0x2C0000 >> 14; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Give chariot control of the chip. */ + WriteParams.ulWriteAddress = 0x712; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + 0x2C0000 + 0xC; + ulTempAddress = 0x300000 + 0x0800; + WriteParams.usWriteData = (UINT16)( ( ulTempAddress >> 16 ) & 0x07FF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + 0x2C0000 + 0xE; + WriteParams.usWriteData = (UINT16)( ( ulTempAddress >> 0 ) & 0xFF00 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write the init PGSP event in place. */ + WriteParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + 0x800; + WriteParams.usWriteData = 0x0200; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + 0x802; + WriteParams.usWriteData = 0x02A0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Also write the register 710, which tells PGSP how many tones are supported. */ + WriteParams.ulWriteAddress = 0x710; + WriteParams.usWriteData = 0x0000; + WriteParams.usWriteData |= pChipConfig->pbyImageFile[ 0x7FA ] << 8; + WriteParams.usWriteData |= pChipConfig->pbyImageFile[ 0x7FB ] << 0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Start both processors in the NLP. */ + WriteParams.ulWriteAddress = 0x373FE; + WriteParams.usWriteData = 0x00FF; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x37BFE; + WriteParams.usWriteData = 0x00FE; /* Tell processor 1 to just go to sleep. */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x37FC6; + WriteParams.usWriteData = 0x8004; /* First PC.*/ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x37FD0; + WriteParams.usWriteData = 0x0002; /* Take out of reset. */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x37FD2; + WriteParams.usWriteData = 0x0002; /* Take out of reset. */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Start processor in the AF. */ + for ( i = 0; i < 16; i ++ ) + { + WriteParams.ulWriteAddress = cOCT6100_POUCH_BASE + ( i * 2 ); + if ( i == 9 ) + { + if ( pSharedInfo->ChipConfig.fEnableProductionBist == TRUE ) + { + WriteParams.usWriteData = cOCT6100_PRODUCTION_BOOT_TYPE; + } + else + { + WriteParams.usWriteData = cOCT6100_AF_BOOT_TYPE; + } + } + else + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Check if the production BIST mode was requested. */ + if ( pSharedInfo->ChipConfig.fEnableProductionBist == TRUE ) + { + UINT32 ulTotalElements = 3; + UINT32 ulCrcKey; + UINT32 aulMessage[ 4 ]; + UINT32 ulWriteAddress = 0x20 + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + + /* Magic key. */ + aulMessage[ 0 ] = 0xCAFECAFE; + /* Memory size. */ + aulMessage[ 1 ] = pSharedInfo->MiscVars.ulTotalMemSize; + /* Loop count. */ + aulMessage[ 2 ] = pSharedInfo->ChipConfig.ulNumProductionBistLoops; + /* CRC initialized. */ + aulMessage[ 3 ] = 0; + + ulResult = Oct6100ApiProductionCrc( f_pApiInstance, aulMessage, ulTotalElements, &ulCrcKey ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + aulMessage[ 3 ] = ulCrcKey; + + /* Write the message to the external memory. */ + for ( i = 0; i < ulTotalElements + 1; i ++ ) + { + ulResult = Oct6100ApiWriteDword( f_pApiInstance, ulWriteAddress + i * 4, aulMessage[ i ] ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + WriteParams.ulWriteAddress = 0xFFFC6; + WriteParams.usWriteData = 0x1284; /* First PC.*/ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0xFFFD0; + WriteParams.usWriteData = 0x0002; /* Take out of reset. */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + while ( ulAfCpuUp == FALSE ) + { + if ( ulAfCpuUp == FALSE ) + { + ReadParams.ulReadAddress = cOCT6100_POUCH_BASE; + ReadParams.pusReadData = &usReadHighData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ReadParams.ulReadAddress += 2; + ReadParams.pusReadData = &usReadData; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( pSharedInfo->ChipConfig.fEnableProductionBist == TRUE ) + { + /* Should read 0x0007 when bisting. */ + if ( ( usReadHighData & 0xFFFF ) == cOCT6100_PRODUCTION_BOOT_TYPE ) + { + /* Verify if the bist has started successfully. */ + if ( ( usReadData & 0xFFFF ) == 0x0002 ) + return cOCT6100_ERR_OPEN_PRODUCTION_BIST_CONF_FAILED; + else if ( ( usReadData & 0xFFFF ) != 0xEEEE ) + return cOCT6100_ERR_OPEN_PRODUCTION_BOOT_FAILED; + + ulAfCpuUp = TRUE; + } + } + else /* if ( pSharedInfo->ChipConfig.fEnableProductionBist == FALSE ) */ + { + if ( ( usReadHighData & 0xFFFF ) == cOCT6100_AF_BOOT_TYPE ) + { + /* Verify if the bist succeeded. */ + if ( ( usReadData & 0xFFFF ) != 0x0000 ) + return cOCT6100_ERR_OPEN_FUNCTIONAL_BIST_FAILED; /* Bad chip. */ + + ulAfCpuUp = TRUE; + } + } + } + + ulLoopCounter++; + + if ( ulLoopCounter == cOCT6100_MAX_LOOP_CPU_TIMEOUT ) + return cOCT6100_ERR_OPEN_AF_CPU_TIMEOUT; + } + + /* Return NLP in operationnal mode. */ + WriteParams.ulWriteAddress = 0x2C2; + WriteParams.usWriteData = 0x060E; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x692; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiSetH100Register + +Description: This function will configure the H.100 registers. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiSetH100Register( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + UINT32 i; + UINT32 ulOffset; + BOOL fAllStreamAt2Mhz = TRUE; + const UINT16 ausAdpcmResetContext[32] = { 0x1100, 0x0220, 0x0000, 0x0000, 0x0000, 0x0020, 0x0000, 0x0000, 0x0008, 0x0000, 0x0000, 0x0100, 0x0000, 0x0020, 0x0000, 0x0000, 0x0000, 0x0002, 0x0000, 0x0000, 0x0040, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x0000, 0x0010, 0x0000, 0x0000, 0x0000}; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get local pointer to the chip configuration structure. */ + pChipConfig = &f_pApiInstance->pSharedInfo->ChipConfig; + + /* Initialize the process context and user chip ID once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Set the Global OE bit. */ + WriteParams.ulWriteAddress = 0x300; + WriteParams.usWriteData = 0x0004; + + /* Set the number of streams. */ + switch( pChipConfig->byMaxTdmStreams ) + { + case 32: + WriteParams.usWriteData |= ( 0 << 3 ); + break; + case 16: + WriteParams.usWriteData |= ( 1 << 3 ); + break; + case 8: + WriteParams.usWriteData |= ( 2 << 3 ); + break; + case 4: + WriteParams.usWriteData |= ( 3 << 3 ); + break; + default: + break; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the stream frequency. */ + WriteParams.ulWriteAddress = 0x330; + WriteParams.usWriteData = 0x0000; + for ( i = 0; i < (UINT32)(pChipConfig->byMaxTdmStreams / 4); i++) + { + ulOffset = i*2; + switch( pChipConfig->aulTdmStreamFreqs[ i ] ) + { + case cOCT6100_TDM_STREAM_FREQ_2MHZ: + WriteParams.usWriteData |= ( 0x0 << ulOffset ); + break; + case cOCT6100_TDM_STREAM_FREQ_4MHZ: + WriteParams.usWriteData |= ( 0x1 << ulOffset ); + fAllStreamAt2Mhz = FALSE; + break; + case cOCT6100_TDM_STREAM_FREQ_8MHZ: + WriteParams.usWriteData |= ( 0x2 << ulOffset ); + fAllStreamAt2Mhz = FALSE; + break; + default: + break; + } + } + + /* Set the stream to 16 MHz if the fast H.100 mode is selected. */ + if ( pChipConfig->fEnableFastH100Mode == TRUE ) + { + fAllStreamAt2Mhz = FALSE; + WriteParams.usWriteData = 0xFFFF; + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + { + /* Make the chip track both clock A and B to perform fast H.100 mode. */ + WriteParams.ulWriteAddress = 0x322; + WriteParams.usWriteData = 0x0004; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Enable the fast H.100 mode. */ + WriteParams.ulWriteAddress = 0x332; + WriteParams.usWriteData = 0x0003; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + WriteParams.ulWriteAddress = 0x376; + WriteParams.usWriteData = (UINT16)( pSharedInfo->MiscVars.usTdmClkBoundary ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Select delay for early clock (90 and 110). */ + WriteParams.ulWriteAddress = 0x378; + if ( pSharedInfo->ChipConfig.fEnableFastH100Mode == TRUE ) + WriteParams.usWriteData = 0x000A; + else + { + /* Set the TDM sampling. */ + if ( pSharedInfo->ChipConfig.byTdmSampling == cOCT6100_TDM_SAMPLE_AT_RISING_EDGE ) + { + WriteParams.usWriteData = 0x0AF0; + } + else if ( pSharedInfo->ChipConfig.byTdmSampling == cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE ) + { + WriteParams.usWriteData = 0x0A0F; + } + else /* pSharedInfo->ChipConfig.ulTdmSampling == cOCT6100_TDM_SAMPLE_AT_3_QUARTERS */ + { + WriteParams.usWriteData = 0x0A08; + } + } + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Protect chip by preventing too rapid timeslot arrival (mclk == 133 MHz). */ + WriteParams.ulWriteAddress = 0x37A; + WriteParams.usWriteData = (UINT16)pSharedInfo->MiscVars.usMaxH100Speed; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Allow H.100 TS to progress. */ + WriteParams.ulWriteAddress = 0x382; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set by-pass mode. */ + WriteParams.ulWriteAddress = 0x50E; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* TDMIE bits. */ + WriteParams.ulWriteAddress = 0x500; + WriteParams.usWriteData = 0x0003; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write normal ADPCM reset values in ADPCM context 1344. */ + for(i=0;i<32;i++) + { + WriteParams.ulWriteAddress = 0x140000 + ( 0x40 * 1344 ) + ( i * 2 ); + WriteParams.usWriteData = ausAdpcmResetContext[i]; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Make sure delay flops are configured correctly if all streams are at 2 MHz. */ + if ( fAllStreamAt2Mhz == TRUE ) + { + /* Setup H.100 sampling to lowest value. */ + WriteParams.ulWriteAddress = 0x144; + WriteParams.usWriteData = 0x4041; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x378; + WriteParams.usWriteData = 0x0A00; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiWriteMiscellaneousRegisters + +Description: This function will write to various registers to activate the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiWriteMiscellaneousRegisters( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_WRITE_PARAMS WriteParams; + UINT32 ulResult; + + /* Initialize the process context and user chip ID once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + /* Free the interrupt pin of the chip (i.e. remove minimum time requirement between interrupts). */ + WriteParams.ulWriteAddress = 0x214; + WriteParams.usWriteData = 0x0000; + if ( f_pApiInstance->pSharedInfo->ChipConfig.byInterruptPolarity == cOCT6100_ACTIVE_HIGH_POLARITY ) + WriteParams.usWriteData |= 0x4000; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write MT chariot interval */ + WriteParams.ulWriteAddress = 0x2C2; + if ( f_pApiInstance->pSharedInfo->ImageInfo.usMaxNumberOfChannels > 640 ) + WriteParams.usWriteData = 0x05EA; + else if ( f_pApiInstance->pSharedInfo->ImageInfo.usMaxNumberOfChannels > 513 ) + WriteParams.usWriteData = 0x0672; + else /* if ( f_pApiInstance->pSharedInfo->ImageInfo.usMaxNumberOfChannels <= 513 ) */ + WriteParams.usWriteData = 0x0750; + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write set second part5 time. */ + WriteParams.ulWriteAddress = 0x2C4; + WriteParams.usWriteData = 0x04A0; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Write CPU bucket timer to guarantee 200 cycles between each CPU access. */ + WriteParams.ulWriteAddress = 0x234; + WriteParams.usWriteData = 0x0804; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x236; + WriteParams.usWriteData = 0x0100; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCreateSerializeObjects + +Description: Creates a handle to each serialization object used by the API. + + Note that in a multi-process system the user's process context + structure pointer is needed by this function. Thus, the + pointer must be valid. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_ulUserChipId User chip ID for this serialization object. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiCreateSerializeObjects( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulUserChipId ) +{ + tOCT6100_CREATE_SERIALIZE_OBJECT CreateSerObj; + UINT32 ulResult; + CHAR szSerObjName[ 64 ] = "Oct6100ApiXXXXXXXXApiSerObj"; + + + /* Set some parameters of the create structure once and for all. */ + CreateSerObj.pProcessContext = f_pApiInstance->pProcessContext; + CreateSerObj.pszSerialObjName = szSerObjName; + + /*----------------------------------------------------------------------*/ + /* Set the chip ID in the semaphore name. */ + szSerObjName[ 10 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 28 ) & 0xFF ); + szSerObjName[ 11 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 24 ) & 0xFF ); + szSerObjName[ 12 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 20 ) & 0xFF ); + szSerObjName[ 13 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 16 ) & 0xFF ); + szSerObjName[ 14 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 12 ) & 0xFF ); + szSerObjName[ 15 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 8 ) & 0xFF ); + szSerObjName[ 16 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 4 ) & 0xFF ); + szSerObjName[ 17 ] = (CHAR) Oct6100ApiHexToAscii( (f_ulUserChipId >> 0 ) & 0xFF ); + + ulResult = Oct6100UserCreateSerializeObject( &CreateSerObj ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + f_pApiInstance->ulApiSerObj = CreateSerObj.ulSerialObjHndl; + /*----------------------------------------------------------------------*/ + + + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiDestroySerializeObjects + +Description: Destroy handles to each serialization object used by the API. + + Note that in a multi-process system the user's process context + structure pointer is needed by this function. Thus, the + pointer must be valid. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiDestroySerializeObjects( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tOCT6100_DESTROY_SERIALIZE_OBJECT DestroySerObj; + UINT32 ulResult; + + /* Set some parameters of the create structure once and for all. */ + DestroySerObj.pProcessContext = f_pApiInstance->pProcessContext; + DestroySerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj; + + ulResult = Oct6100UserDestroySerializeObject( &DestroySerObj ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRunEgo + +Description: Private function used to communicate with the internal processors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +f_fStoreFlag Type of access performed. (Load or Store) +f_ulNumEntry Number of access. +f_aulEntry Array of access to perform. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiRunEgo( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN BOOL f_fStoreFlag, + IN UINT32 f_ulNumEntry, + OUT PUINT32 f_aulEntry ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHIP_CONFIG pChipConfig; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulResult; + UINT32 aulCpuLsuCmd[ 2 ]; + UINT16 usReadData; + UINT32 i; + BOOL fConditionFlag = TRUE; + UINT32 ulLoopCounter = 0; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Get local pointer to the chip configuration structure. */ + pChipConfig = &f_pApiInstance->pSharedInfo->ChipConfig; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* No more than 2 entries may be requested. */ + if ( f_ulNumEntry > 2 ) + return cOCT6100_ERR_FATAL_1B; + + /* Write the requested entries at address reserved for CPU. */ + for( i = 0; i < f_ulNumEntry; i++ ) + { + WriteParams.ulWriteAddress = cOCT6100_PART1_API_SCRATCH_PAD + ( 0x8 * i ); + WriteParams.usWriteData = (UINT16)(( f_aulEntry[ i * 2 ] >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( f_aulEntry[ i * 2 ] & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)(( f_aulEntry[ (i * 2) + 1] >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( f_aulEntry[ (i * 2) + 1] & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Preincrement code point. */ + pSharedInfo->MiscVars.usCodepoint++; + + /* Create DWORD 0 of command. */ + aulCpuLsuCmd[0] = 0x00000000; + if ( f_fStoreFlag == FALSE ) + aulCpuLsuCmd[0] |= 0xC0000000; /* EGO load. */ + else + aulCpuLsuCmd[0] |= 0xE0000000; /* EGO store. */ + + aulCpuLsuCmd[0] |= (f_ulNumEntry - 1) << 19; + aulCpuLsuCmd[0] |= cOCT6100_PART1_API_SCRATCH_PAD; + + /* Create DWORD 1 of command. */ + aulCpuLsuCmd[1] = 0x00000000; + aulCpuLsuCmd[1] |= ( ( cOCT6100_PART1_API_SCRATCH_PAD + 0x10 ) & 0xFFFF ) << 16; + aulCpuLsuCmd[1] |= pSharedInfo->MiscVars.usCodepoint; + + /* Write the EGO command in the LSU CB. */ + WriteParams.ulWriteAddress = cOCT6100_PART1_CPU_LSU_CB_BASE + ((pSharedInfo->MiscVars.usCpuLsuWritePtr & 0x7) * 0x8 ); + WriteParams.usWriteData = (UINT16)(( aulCpuLsuCmd[ 0 ] >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( aulCpuLsuCmd[ 0 ] & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)(( aulCpuLsuCmd[ 1 ] >> 16 ) & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( aulCpuLsuCmd[ 1 ] & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Post increment the write pointer. */ + pSharedInfo->MiscVars.usCpuLsuWritePtr++; + + /* Indicate new write pointer position to HW. */ + WriteParams.ulWriteAddress = cOCT6100_PART1_EGO_REG + 0x5A; + WriteParams.usWriteData = (UINT16)( pSharedInfo->MiscVars.usCpuLsuWritePtr & 0x7 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Wait for codepoint to be updated before returning. */ + while( fConditionFlag ) + { + ReadParams.ulReadAddress = cOCT6100_PART1_API_SCRATCH_PAD + 0x12; + usReadData = (UINT16)( pSharedInfo->MiscVars.usCodepoint ); + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData == pSharedInfo->MiscVars.usCodepoint ) + fConditionFlag = FALSE; + + ulLoopCounter++; + + if ( ulLoopCounter == cOCT6100_MAX_LOOP ) + return cOCT6100_ERR_OPEN_EGO_TIMEOUT; + } + + /* CRC error bit must be zero. */ + ReadParams.ulReadAddress = 0x202; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( ( usReadData & 0x0400 ) != 0 ) + return cOCT6100_ERR_OPEN_CORRUPTED_IMAGE; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiCreateEgoEntry + +Description: Private function used to create an access structure to be sent + to the internal processors. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_ulExternalAddress External memory address for the access. +f_ulInternalAddress Which process should receive the command. +f_ulNumBytes Number of bytes associated to the access. +f_aulEntry Array of access to perform. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiCreateEgoEntry( + IN UINT32 f_ulExternalAddress, + IN UINT32 f_ulInternalAddress, + IN UINT32 f_ulNumBytes, + OUT UINT32 f_aulEntry[ 2 ] ) +{ + f_aulEntry[0] = 0x80000000; + f_aulEntry[0] |= f_ulExternalAddress & 0x07FFFFFC; + + f_aulEntry[1] = 0x0011C000; + f_aulEntry[1] |= (f_ulNumBytes / 8) << 23; + f_aulEntry[1] |= (f_ulInternalAddress >> 2) & 0x3FFF; + + return cOCT6100_ERR_OK; +} + + + + + + + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitChannels + +Description: This function will initialize all the channels to power down. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiInitChannels( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 i; + UINT32 ulResult; + tOCT6100_WRITE_BURST_PARAMS BurstParams; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT16 usReadData; + UINT32 ulTempData; + UINT32 ulBaseAddress; + UINT32 ulFeatureBytesOffset; + UINT32 ulFeatureBitOffset; + UINT32 ulFeatureFieldLength; + UINT32 ulMask; + UINT16 ausWriteData[ 4 ]; + UINT16 usLoopCount = 0; + UINT16 usWriteData = 0; + UINT16 usMclkRead; + UINT16 usLastMclkRead; + UINT16 usMclkDiff; + UINT32 ulNumberOfCycleToWait; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + BurstParams.pusWriteData = ausWriteData; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + /* Verify that the image has enough memory to work correctly. */ + if ( ( pSharedInfo->MiscVars.ulTotalMemSize + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS ) < pSharedInfo->MemoryMap.ulFreeMemBaseAddress ) + return cOCT6100_ERR_OPEN_INSUFFICIENT_EXTERNAL_MEMORY; + + /* Verify that the tail length is supported by the device.*/ + if ( pSharedInfo->ChipConfig.usTailDisplacement > pSharedInfo->ImageInfo.usMaxTailDisplacement ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_TAIL_DISPLACEMENT_VALUE; + + /* Verify that acoustic echo is supported by the device. */ + if ( pSharedInfo->ChipConfig.fEnableAcousticEcho == TRUE && pSharedInfo->ImageInfo.fAcousticEcho == FALSE ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_ACOUSTIC_ECHO; + + /* Verify that the image supports all the requested channels. */ + if ( pSharedInfo->ChipConfig.usMaxChannels > pSharedInfo->ImageInfo.usMaxNumberOfChannels ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_MAX_ECHO_CHANNELS_VALUE; + + /* Max number of channels the image supports + 1 for channel recording, if requested */ + if ( ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + && ( pSharedInfo->ImageInfo.usMaxNumberOfChannels < cOCT6100_MAX_ECHO_CHANNELS ) + && ( pSharedInfo->ChipConfig.usMaxChannels == pSharedInfo->ImageInfo.usMaxNumberOfChannels ) ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_MAX_ECHO_CHANNELS_VALUE; + + /* Initialize the memory for all required channels. */ + for( i = 0; i < f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels; i++ ) + { + /*==============================================================================*/ + /* Configure the Global Static Configuration memory of the channel. */ + + ulBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( i * cOCT6100_CHANNEL_ROOT_SIZE ) + cOCT6100_CHANNEL_ROOT_GLOBAL_CONF_OFFSET; + + /* Set the PGSP context base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( i * pSharedInfo->MemoryMap.ulChanMainMemSize ) + cOCT6100_CH_MAIN_PGSP_CONTEXT_OFFSET; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_PGSP_CONTEXT_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the PGSP init context base address. */ + ulTempData = ( cOCT6100_IMAGE_FILE_BASE + 0x200 ) & 0x07FFFFFF; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_PGSP_INIT_CONTEXT_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the RIN circular buffer base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( i * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainRinCBMemOfst; + + /* Set the circular buffer size. */ + ulTempData &= 0xFFFFFF00; + if (( pSharedInfo->MemoryMap.ulChanMainRinCBMemSize & 0xFFFF00FF ) != 0 ) + return cOCT6100_ERR_CHANNEL_INVALID_RIN_CB_SIZE; + ulTempData |= pSharedInfo->MemoryMap.ulChanMainRinCBMemSize >> 8; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_RIN_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the SIN circular buffer base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( i * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainSinCBMemOfst; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_SIN_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set the SOUT circular buffer base address. */ + ulTempData = pSharedInfo->MemoryMap.ulChanMainMemBase + ( i * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->MemoryMap.ulChanMainSoutCBMemOfst;; + + WriteParams.ulWriteAddress = ulBaseAddress + cOCT6100_GSC_SOUT_CIRC_BUFFER_BASE_ADD_OFFSET; + WriteParams.usWriteData = (UINT16)( ulTempData >> 16 ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress += 2; + WriteParams.usWriteData = (UINT16)( ulTempData & 0xFFFF ); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*==============================================================================*/ + } + + /* Put all channel in powerdown mode "3". */ + for( i = 0; i < f_pApiInstance->pSharedInfo->ChipConfig.usMaxChannels; i++ ) + { + WriteParams.ulWriteAddress = 0x014000 + (i*4) + 0; + WriteParams.usWriteData = 0x85FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x014000 + (i*4) + 2; + WriteParams.usWriteData = 0xC5FF; /* TSI index 1535 reserved for power-down mode */ + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Set the maximum number of channels. */ + WriteParams.ulWriteAddress = 0x690; + if ( pSharedInfo->ImageInfo.usMaxNumberOfChannels < 384 ) + WriteParams.usWriteData = 384; + else + WriteParams.usWriteData = (UINT16)pSharedInfo->ImageInfo.usMaxNumberOfChannels; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Set power-dowm TSI chariot memory to silence. */ + for( i = 0; i < 6; i++ ) + { + WriteParams.ulWriteAddress = 0x20000 + ( i * 0x1000 ) + ( 1534 * 2 ); + WriteParams.usWriteData = 0xFF; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = 0x20000 + ( i * 0x1000 ) + ( 1535 * 2 ); + WriteParams.usWriteData = 0xFF; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Remove chariot hold. */ + WriteParams.ulWriteAddress = 0x500; + WriteParams.usWriteData = 0x0001; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for( usLoopCount = 0; usLoopCount < 4096; usLoopCount++ ) + { + if ( (usLoopCount % 16) < 8 ) + { + usWriteData = (UINT16)((usLoopCount / 16) << 7); + usWriteData |= (UINT16)((usLoopCount % 8)); + } + else + { + usWriteData = (UINT16)((usLoopCount / 16) << 7); + usWriteData |= (UINT16)((usLoopCount % 8)); + usWriteData |= 0x78; + } + + /* Set timeslot pointer. */ + WriteParams.ulWriteAddress = 0x50E; + WriteParams.usWriteData = 0x0003; + WriteParams.usWriteData |= usWriteData << 2; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Now read the mclk counter. */ + ReadParams.ulReadAddress = 0x30A; + ReadParams.pusReadData = &usLastMclkRead; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + do { + ReadParams.pusReadData = &usMclkRead; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( ( usLoopCount % 16 ) != 15 ) + { + ulNumberOfCycleToWait = 133; + } + else + { + ulNumberOfCycleToWait = 20000; + } + + /* Evaluate the difference. */ + usMclkDiff = (UINT16)(( usMclkRead - usLastMclkRead ) & 0xFFFF); + + } while( usMclkDiff <= ulNumberOfCycleToWait ); + } + + /* Back to normal mode. */ + WriteParams.ulWriteAddress = 0x50E; + WriteParams.usWriteData = 0x0000; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check for CRC errors. */ + ReadParams.pusReadData = &usReadData; + ReadParams.ulReadAddress = 0x202; + + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( (usReadData & 0x400) != 0x0000 ) + return cOCT6100_ERR_OPEN_CRC_ERROR; + + /* Clear the error rol raised by manually moving the clocks. */ + WriteParams.ulWriteAddress = 0x502; + WriteParams.usWriteData = 0x0002; + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*======================================================================*/ + /* Write the tail displacement value in external memory. */ + + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PouchTailDisplOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PouchTailDisplOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PouchTailDisplOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + ulTempData &= (~ulMask); + + /* Set the tail displacement. */ + ulTempData |= (pSharedInfo->ChipConfig.usTailDisplacement << ulFeatureBitOffset ); + + /* Write the DWORD where the field is located. */ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /*======================================================================*/ + + + /*======================================================================*/ + /* Clear the pouch counter, if present. */ + + if ( pSharedInfo->DebugInfo.fPouchCounter == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.PouchCounterFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.PouchCounterFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.PouchCounterFieldOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Clear previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Clear counter! */ + ulTempData &= (~ulMask); + + /* Write the DWORD where the field is located.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* The ISR has not yet been called. Set the appropriate bit in external memory. */ + if ( pSharedInfo->DebugInfo.fIsIsrCalledField == TRUE ) + { + ulFeatureBytesOffset = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.usDwordOffset * 4; + ulFeatureBitOffset = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.byBitOffset; + ulFeatureFieldLength = pSharedInfo->MemoryMap.IsIsrCalledFieldOfst.byFieldSize; + + ulResult = Oct6100ApiReadDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + &ulTempData ); + + /* Read previous value set in the feature field.*/ + mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask ); + + /* Toggle the bit to '1'. */ + ulTempData |= 1 << ulFeatureBitOffset; + + /* Write the DWORD where the field is located.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, + cOCT6100_POUCH_BASE + ulFeatureBytesOffset, + ulTempData ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /*======================================================================*/ + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitToneInfo + +Description: This function will parse the software image and retrieve + the information about the tones that it supports. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiInitToneInfo( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + UINT32 ulResult; + + PUINT8 pszToneInfoStart = NULL; + PUINT8 pszToneInfoEnd = NULL; + + PUINT8 pszCurrentInfo; + PUINT8 pszNextInfo; + + UINT32 ulToneEventNumber; + UINT32 ulTempValue; + UINT32 ulNumCharForValue; + UINT32 ulUniqueToneId; + UINT32 ulToneNameSize; + UINT32 ulOffset = 0; + + UINT32 i; + + /* Init the tone detector parameter. */ + f_pApiInstance->pSharedInfo->ImageInfo.byNumToneDetectors = 0; + + /* Find the start and the end of the tone info section. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize > 4096 ) + { + /* For performance reasons, and since the tone detector information */ + /* is always located at the end of the image file, try to start from the end */ + /* of the buffer. */ + + ulOffset = f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize - 2048; + pszToneInfoStart = Oct6100ApiStrStr( f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + ulOffset, + (PUINT8)cOCT6100_TONE_INFO_START_STRING, + f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize ); + + /* Check if the information was found. */ + if ( pszToneInfoStart == NULL ) + { + /* Try again, but giving a larger string to search. */ + ulOffset = f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize - 4096; + pszToneInfoStart = Oct6100ApiStrStr( f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + ulOffset, + (PUINT8)cOCT6100_TONE_INFO_START_STRING, + f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize ); + + } + } + + if ( pszToneInfoStart == NULL ) + { + /* Travel through the whole file buffer. */ + pszToneInfoStart = Oct6100ApiStrStr( f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile, + (PUINT8)cOCT6100_TONE_INFO_START_STRING, + f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize ); + } + /* We have to return immediatly if no tones are found. */ + if ( pszToneInfoStart == NULL ) + return cOCT6100_ERR_OK; + + /* The end of the tone detector information is after the beginning of the tone information. */ + pszToneInfoEnd = Oct6100ApiStrStr( pszToneInfoStart, + (PUINT8)cOCT6100_TONE_INFO_STOP_STRING, + f_pApiInstance->pSharedInfo->ChipConfig.pbyImageFile + f_pApiInstance->pSharedInfo->ChipConfig.ulImageSize ); + if ( pszToneInfoEnd == NULL ) + return cOCT6100_ERR_OPEN_TONE_INFO_STOP_TAG_NOT_FOUND; + + /* Find and process all tone events within the region. */ + pszCurrentInfo = Oct6100ApiStrStr( pszToneInfoStart, (PUINT8)cOCT6100_TONE_INFO_EVENT_STRING, pszToneInfoEnd ); + + while ( pszCurrentInfo != NULL ) + { + /* Skip the string. */ + pszCurrentInfo += ( Oct6100ApiStrLen( (PUINT8)cOCT6100_TONE_INFO_EVENT_STRING ) ); + + /* Extract the number of char used to represent the tone event number ( 1 or 2 ). */ + pszNextInfo = Oct6100ApiStrStr( pszCurrentInfo, (PUINT8)",", pszToneInfoEnd ); + ulNumCharForValue = pszNextInfo - pszCurrentInfo; + + /* Retreive the event number */ + ulToneEventNumber = 0; + for ( i = ulNumCharForValue; i > 0; i-- ) + { + ulResult = Oct6100ApiAsciiToHex( *pszCurrentInfo, &ulTempValue ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulToneEventNumber |= ( ulTempValue << (( i - 1) * 4 ) ); + pszCurrentInfo++; + } + + if ( ulToneEventNumber >= cOCT6100_MAX_TONE_EVENT ) + return cOCT6100_ERR_OPEN_INVALID_TONE_EVENT; + + /* Skip the comma and the 0x. */ + pszCurrentInfo += 3; + + /*======================================================================*/ + /* Retreive the unique tone id. */ + ulUniqueToneId = 0; + for ( i = 0; i < 8; i++ ) + { + ulResult = Oct6100ApiAsciiToHex( *pszCurrentInfo, &ulTempValue ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulOffset = 28 - ( i * 4 ); + ulUniqueToneId |= ( ulTempValue << ulOffset ); + pszCurrentInfo++; + } + + /*======================================================================*/ + + /* Skip the comma. */ + pszCurrentInfo++; + + /* Find out where the next event info starts */ + pszNextInfo = Oct6100ApiStrStr( pszCurrentInfo,(PUINT8) cOCT6100_TONE_INFO_EVENT_STRING, pszToneInfoEnd ); + if ( pszNextInfo == NULL ) + pszNextInfo = pszToneInfoEnd; + + /* Extract the name size. */ + ulToneNameSize = pszNextInfo - pszCurrentInfo - 2; /* - 2 for 0x0D and 0x0A.*/ + + if ( ulToneNameSize > cOCT6100_TLV_MAX_TONE_NAME_SIZE ) + return cOCT6100_ERR_OPEN_INVALID_TONE_NAME; + + /* Copy the tone name into the image info structure. */ + ulResult = Oct6100UserMemCopy( f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].aszToneName, + pszCurrentInfo, + ulToneNameSize ); + + + + /* Update the tone info into the image info structure. */ + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulToneID = ulUniqueToneId; + /* Find out the port on which this tone detector is associated. */ + switch( (ulUniqueToneId >> 28) & 0xF ) + { + case 1: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_CHANNEL_PORT_ROUT; + break; + + case 2: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_CHANNEL_PORT_SIN; + break; + + case 4: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_CHANNEL_PORT_SOUT; + break; + + case 5: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_CHANNEL_PORT_ROUT_SOUT; + break; + + default: + f_pApiInstance->pSharedInfo->ImageInfo.aToneInfo[ ulToneEventNumber ].ulDetectionPort = cOCT6100_INVALID_PORT; + break; + } + + /* Find out where the next event info starts */ + pszNextInfo = Oct6100ApiStrStr( pszCurrentInfo,(PUINT8) cOCT6100_TONE_INFO_EVENT_STRING, pszToneInfoEnd ); + /* Update the current info pointer. */ + pszCurrentInfo = pszNextInfo; + + f_pApiInstance->pSharedInfo->ImageInfo.byNumToneDetectors++; + } + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiExternalMemoryBist + +Description: Tests the functionality of the external memories. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiExternalMemoryBist( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulMemSize = 0; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Test the external memory. */ + switch ( pSharedInfo->ChipConfig.ulMemoryChipSize ) + { + case cOCT6100_MEMORY_CHIP_SIZE_8MB: + ulMemSize = cOCT6100_SIZE_8M; + break; + case cOCT6100_MEMORY_CHIP_SIZE_16MB: + ulMemSize = cOCT6100_SIZE_16M; + break; + case cOCT6100_MEMORY_CHIP_SIZE_32MB: + ulMemSize = cOCT6100_SIZE_32M; + break; + case cOCT6100_MEMORY_CHIP_SIZE_64MB: + ulMemSize = cOCT6100_SIZE_64M; + break; + case cOCT6100_MEMORY_CHIP_SIZE_128MB: + ulMemSize = cOCT6100_SIZE_128M; + break; + default: + return cOCT6100_ERR_FATAL_D9; + } + + ulMemSize *= pSharedInfo->ChipConfig.byNumMemoryChips; + + ulResult = Oct6100ApiRandomMemoryWrite( f_pApiInstance, cOCT6100_EXTERNAL_MEM_BASE_ADDRESS, ulMemSize, 16, 1000, cOCT6100_ERR_OPEN_EXTERNAL_MEM_BIST_FAILED ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Make sure the user I/O functions are working as required. */ + ulResult = Oct6100ApiUserIoTest( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiGenerateNumber + +Description: Generate a number using an index. Passing the same + index generates the same number. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_ulIndex Index used to generate the random number. +f_ulDataMask Data mask to apply to generated number. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT16 Oct6100ApiGenerateNumber( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulIndex, + IN UINT32 f_ulDataMask ) +{ + UINT16 usGeneratedNumber; + + usGeneratedNumber = (UINT16)( ( ( ~( f_ulIndex - 1 ) ) & 0xFF00 ) | ( ( f_ulIndex + 1 ) & 0xFF ) ); + + return (UINT16)( usGeneratedNumber & f_ulDataMask ); +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiRandomMemoryWrite + +Description: Writes to f_ulNumAccesses random locations in the indicated + memory and read back to test the operation of that memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. +f_ulMemBase Base address of the memory access. +f_ulMemSize Size of the memory to be tested. +f_ulNumDataBits Number of data bits. +f_ulNumAccesses Number of random access to be perform. +f_ulErrorCode Error code to be returned if the bist fails. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiRandomMemoryWrite( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN UINT32 f_ulMemBase, + IN UINT32 f_ulMemSize, + IN UINT32 f_ulNumDataBits, + IN UINT32 f_ulNumAccesses, + IN UINT32 f_ulErrorCode ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_PARAMS WriteParams; + tOCT6100_READ_PARAMS ReadParams; + UINT32 ulDataMask; + UINT32 ulResult, i, j; + UINT32 ulBistAddress; + UINT16 usReadData; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Make sure we don't perform more access then the size of our BIST resources. */ + if ( f_ulNumAccesses > 1024 ) + return cOCT6100_ERR_FATAL_C0; + + /* Determine mask for number of data bits. */ + ulDataMask = (1 << f_ulNumDataBits) - 1; + + /* Bist all data pin. */ + for ( i = 0; i < 32; i += 2 ) + { + WriteParams.ulWriteAddress = f_ulMemBase + i * 2; + WriteParams.usWriteData = (UINT16)(0x1 << (i / 2)); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + WriteParams.ulWriteAddress = f_ulMemBase + i * 2 + 2; + WriteParams.usWriteData = (UINT16)(0x1 << (i / 2)); + + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Read back the data written. */ + for ( i = 0; i < 32; i += 2 ) + { + ReadParams.ulReadAddress = f_ulMemBase + i * 2; + ReadParams.pusReadData = &usReadData; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != (UINT16)(0x1 << (i / 2)) ) + return f_ulErrorCode; + + ReadParams.ulReadAddress = f_ulMemBase + i * 2 + 2; + ReadParams.pusReadData = &usReadData; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != (UINT16)(0x1 << (i / 2)) ) + return f_ulErrorCode; + } + + /* Perform the first write at address 0 + mem base */ + j = 0; + WriteParams.ulWriteAddress = f_ulMemBase; + WriteParams.usWriteData = Oct6100ApiGenerateNumber( f_pApiInstance, j, ulDataMask ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Try each address line of the memory. */ + for ( i = 2, j = 1; i < f_ulMemSize; i <<= 1, j++ ) + { + WriteParams.ulWriteAddress = ( f_ulMemBase + i ); + WriteParams.usWriteData = Oct6100ApiGenerateNumber( f_pApiInstance, j, ulDataMask ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + for ( i = 0; i < j; i++ ) + { + if ( i > 0 ) + ReadParams.ulReadAddress = ( f_ulMemBase + ( 0x1 << i ) ); + else + ReadParams.ulReadAddress = f_ulMemBase; + ReadParams.pusReadData = &usReadData; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( usReadData != Oct6100ApiGenerateNumber( f_pApiInstance, i, ulDataMask ) ) + return f_ulErrorCode; + } + + /* Write to random addresses of the memory. */ + for ( i = 0; i < f_ulNumAccesses; i++ ) + { + ulBistAddress = (UINT16)Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ) << 16; + ulBistAddress |= (UINT16)Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ); + ulBistAddress &= f_ulMemSize - 2; + ulBistAddress |= f_ulMemBase; + + WriteParams.ulWriteAddress = ulBistAddress; + WriteParams.usWriteData = Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ); + mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + for ( i = 0; i < f_ulNumAccesses; i++ ) + { + ulBistAddress = (UINT16)Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ) << 16; + ulBistAddress |= (UINT16)Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ); + ulBistAddress &= f_ulMemSize - 2; + ulBistAddress |= f_ulMemBase; + + ReadParams.ulReadAddress = ulBistAddress; + ReadParams.pusReadData = &usReadData; + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + if ( ( usReadData & ulDataMask ) != ( Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ) & ulDataMask ) ) + return f_ulErrorCode; + } + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiUserIoTest + +Description: This function will verify the correct functionality of + the following user functions: + + - Oct6100UserDriverWriteBurstApi + - Oct6100UserDriverWriteSmearApi + - Oct6100UserDriverReadBurstApi + + The Oct6100UserDriverWriteApi and Oct6100UserDriverReadApi + functions do not need to be tested here as this has be done in + the external memory bisting function above. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiUserIoTest( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_BURST_PARAMS WriteBurstParams; + tOCT6100_WRITE_SMEAR_PARAMS WriteSmearParams; + tOCT6100_READ_PARAMS ReadParams; + tOCT6100_READ_BURST_PARAMS ReadBurstParams; + UINT32 ulResult, i; + UINT16 usReadData; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Set the process context and user chip ID parameters once and for all. */ + WriteBurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteBurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + /* Test what the user has specified is the maximum that can be used for a burst. */ + WriteBurstParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + WriteBurstParams.pusWriteData = pSharedInfo->MiscVars.ausSuperArray; + + WriteSmearParams.pProcessContext = f_pApiInstance->pProcessContext; + + WriteSmearParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + /* Test what the user has specified is the maximum that can be used for a smear. */ + WriteSmearParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + + ReadParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + ReadParams.pusReadData = &usReadData; + + ReadBurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + ReadBurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + /* Test what the user has specified is the maximum that can be used for a burst. */ + ReadBurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + ReadBurstParams.pusReadData = pSharedInfo->MiscVars.ausSuperArray; + + + /*======================================================================*/ + /* Write burst check. */ + + WriteBurstParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + /* Set the random data to be written. */ + for ( i = 0; i < WriteBurstParams.ulWriteLength; i++ ) + { + WriteBurstParams.pusWriteData[ i ] = Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ); + } + mOCT6100_DRIVER_WRITE_BURST_API( WriteBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read back pattern using simple read function and make sure we are reading what's expected. */ + ReadParams.ulReadAddress = WriteBurstParams.ulWriteAddress; + for ( i = 0; i < WriteBurstParams.ulWriteLength; i++ ) + { + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the data matches. */ + if ( usReadData != WriteBurstParams.pusWriteData[ i ] ) + { + /* The values do not match. Something seems to be wrong with the WriteBurst user function. */ + return cOCT6100_ERR_OPEN_USER_WRITE_BURST_FAILED; + } + + /* Next address to check. */ + ReadParams.ulReadAddress += 2; + } + + /*======================================================================*/ + + + /*======================================================================*/ + /* Write smear check. */ + + WriteSmearParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS + ( WriteBurstParams.ulWriteLength * 2 ); + /* Set the random data to be written. */ + WriteSmearParams.usWriteData = Oct6100ApiGenerateNumber( f_pApiInstance, Oct6100ApiRand( 0xFFFF ), 0xFFFF ); + mOCT6100_DRIVER_WRITE_SMEAR_API( WriteSmearParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Read back pattern using simple read function and make sure we are reading what's expected. */ + ReadParams.ulReadAddress = WriteSmearParams.ulWriteAddress; + for ( i = 0; i < WriteSmearParams.ulWriteLength; i++ ) + { + mOCT6100_DRIVER_READ_API( ReadParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Check if the data matches. */ + if ( usReadData != WriteSmearParams.usWriteData ) + { + /* The values do not match. Something seems to be wrong with the WriteSmear user function. */ + return cOCT6100_ERR_OPEN_USER_WRITE_SMEAR_FAILED; + } + + /* Next address to check. */ + ReadParams.ulReadAddress += 2; + } + + /*======================================================================*/ + + + /*======================================================================*/ + /* Read burst check. */ + + /* First check with what the WriteBurst function wrote. */ + ReadBurstParams.ulReadAddress = WriteBurstParams.ulWriteAddress; + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for ( i = 0; i < ReadBurstParams.ulReadLength; i++ ) + { + /* Check if the data matches. */ + if ( ReadBurstParams.pusReadData[ i ] != Oct6100ApiGenerateNumber( f_pApiInstance, i, 0xFFFF ) ) + { + /* The values do not match. Something seems to be wrong with the ReadBurst user function. */ + return cOCT6100_ERR_OPEN_USER_READ_BURST_FAILED; + } + } + + /* Then check with what the WriteSmear function wrote. */ + ReadBurstParams.ulReadAddress = WriteSmearParams.ulWriteAddress; + mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult ) + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + for ( i = 0; i < ReadBurstParams.ulReadLength; i++ ) + { + /* Check if the data matches. */ + if ( ReadBurstParams.pusReadData[ i ] != WriteSmearParams.usWriteData ) + { + /* The values do not match. Something seems to be wrong with the ReadBurst user function. */ + return cOCT6100_ERR_OPEN_USER_READ_BURST_FAILED; + } + } + + /*======================================================================*/ + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiExternalMemoryInit + +Description: Initialize the external memory before uploading the image. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiExternalMemoryInit( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_SMEAR_PARAMS SmearParams; + UINT32 ulTotalWordToWrite; + UINT32 ulResult; + + /* Get local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + SmearParams.pProcessContext = f_pApiInstance->pProcessContext; + + SmearParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId; + + /* Clear the first part of the memory. */ + ulTotalWordToWrite = 0x400; + SmearParams.ulWriteAddress = cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + + while ( ulTotalWordToWrite != 0 ) + { + if ( ulTotalWordToWrite >= pSharedInfo->ChipConfig.usMaxRwAccesses ) + SmearParams.ulWriteLength = pSharedInfo->ChipConfig.usMaxRwAccesses; + else + SmearParams.ulWriteLength = ulTotalWordToWrite; + + SmearParams.usWriteData = 0x0; + + mOCT6100_DRIVER_WRITE_SMEAR_API( SmearParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Update the number of words to write. */ + ulTotalWordToWrite -= SmearParams.ulWriteLength; + /* Update the address. */ + SmearParams.ulWriteAddress += ( SmearParams.ulWriteLength * 2 ); + } + + /* Clear the TLV flag.*/ + ulResult = Oct6100ApiWriteDword( f_pApiInstance, cOCT6100_TLV_BASE, 0x0 ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitMixer + +Description: This function will initialize the mixer memory. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiInitMixer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tOCT6100_WRITE_BURST_PARAMS BurstParams; + UINT16 ausWriteData[ 4 ]; + UINT32 ulResult; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + BurstParams.pProcessContext = f_pApiInstance->pProcessContext; + + BurstParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId; + BurstParams.pusWriteData = ausWriteData; + /*======================================================================*/ + /* Initialize the mixer memory if required. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE ) + { + /* Modify the mixer pointer by adding the record event into the link list. */ + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = pSharedInfo->MixerInfo.usRecordSinEventIndex; + pSharedInfo->MixerInfo.usLastSinCopyEventPtr = pSharedInfo->MixerInfo.usRecordSinEventIndex; + pSharedInfo->MixerInfo.usFirstSoutCopyEventPtr = pSharedInfo->MixerInfo.usRecordCopyEventIndex; + pSharedInfo->MixerInfo.usLastSoutCopyEventPtr = pSharedInfo->MixerInfo.usRecordCopyEventIndex; + + /* Program the Sin copy event. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordSinEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(cOCT6100_MIXER_TAIL_NODE & 0x7FF); /* Head node.*/ + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Program the Sout copy event. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE ); + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(pSharedInfo->MixerInfo.usRecordSinEventIndex & 0x7FF); + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the head node. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE; + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(pSharedInfo->MixerInfo.usRecordCopyEventIndex & 0x7FF); + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Init the mixer pointer */ + pSharedInfo->MixerInfo.usFirstSinCopyEventPtr = pSharedInfo->MixerInfo.usRecordSinEventIndex; + } + else + { + /* Configure the head node. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE; + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(cOCT6100_MIXER_TAIL_NODE & 0x7FF); /* Head node. */ + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Configure the tail node. */ + BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + 0x10; + BurstParams.ulWriteLength = 4; + + ausWriteData[ 0 ] = 0x0000; + ausWriteData[ 1 ] = 0x0000; + ausWriteData[ 2 ] = (UINT16)(cOCT6100_MIXER_HEAD_NODE & 0x7FF); /* Head node. */ + ausWriteData[ 3 ] = 0x0000; + + mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiInitRecordResources + +Description: This function will initialize the resources required to + perform recording on a debug channel. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep the + present state of the chip and all its resources. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiInitRecordResources( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + UINT32 ulResult; + + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Check if recording is enabled. */ + if ( pSharedInfo->ChipConfig.fEnableChannelRecording == FALSE ) + return cOCT6100_ERR_OK; + + if ( pSharedInfo->DebugInfo.usRecordMemIndex == cOCT6100_INVALID_INDEX ) + return cOCT6100_ERR_NOT_SUPPORTED_OPEN_DEBUG_RECORD; + + /* Check the provided recording memory index within the SSPX. */ + if ( pSharedInfo->DebugInfo.usRecordMemIndex != ( pSharedInfo->ImageInfo.usMaxNumberOfChannels - 1 ) ) + return cOCT6100_ERR_OPEN_DEBUG_MEM_INDEX; + + /* Reserve the TSI entries for the channel. */ + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, &pSharedInfo->DebugInfo.usRecordRinRoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, &pSharedInfo->DebugInfo.usRecordSinSoutTsiMemIndex ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* Open the debug channel. */ + ulResult = Oct6100ApiDebugChannelOpen( f_pApiInstance ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100FreeResourcesSer + +Description: This function closes all opened channels and frees all + specified global resources used by the chip. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pFreeResources Pointer to user structure in which to choose what + to free. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100FreeResourcesSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN tPOCT6100_FREE_RESOURCES f_pFreeResources ) +{ + tPOCT6100_SHARED_INFO pSharedInfo; + tPOCT6100_API_CHANNEL pChanEntry; + + UINT32 ulResult; + UINT32 i; + + /* Obtain local pointer to shared portion of instance. */ + pSharedInfo = f_pApiInstance->pSharedInfo; + + /* Close all bidirectional channels. */ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxBiDirChannels; i ++ ) + { + tPOCT6100_API_BIDIR_CHANNEL pBiDirChanEntry; + + mOCT6100_GET_BIDIR_CHANNEL_ENTRY_PNT( pSharedInfo, pBiDirChanEntry, i ); + + if ( pBiDirChanEntry->fReserved == TRUE ) + { + tOCT6100_CHANNEL_DESTROY_BIDIR DestroyBidir; + + Oct6100ChannelDestroyBiDirDef( &DestroyBidir ); + + DestroyBidir.ulBiDirChannelHndl = cOCT6100_HNDL_TAG_BIDIR_CHANNEL | (pBiDirChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100ChannelDestroyBiDirSer( f_pApiInstance, &DestroyBidir ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Close all bridge participants. */ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxChannels; i ++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, i ); + if ( pChanEntry->fReserved == TRUE && pChanEntry->usBridgeIndex != cOCT6100_INVALID_INDEX ) + { + /* This channel is on a bridge. */ + tOCT6100_CONF_BRIDGE_CHAN_REMOVE BridgeChanRemove; + tPOCT6100_API_CONF_BRIDGE pBridgeEntry; + + Oct6100ConfBridgeChanRemoveDef( &BridgeChanRemove ); + + /* Obtain a pointer to the conference bridge's list entry. */ + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, pChanEntry->usBridgeIndex ); + + BridgeChanRemove.fRemoveAll = TRUE; + BridgeChanRemove.ulConfBridgeHndl = cOCT6100_HNDL_TAG_CONF_BRIDGE | (pBridgeEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | pChanEntry->usBridgeIndex; + + ulResult = Oct6100ConfBridgeChanRemoveSer( f_pApiInstance, &BridgeChanRemove ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Close all opened channels. This will bring the broadcast TSSTs with it. */ + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxChannels; i ++ ) + { + mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, i ); + + if ( pChanEntry->fReserved == TRUE ) + { + tOCT6100_CHANNEL_CLOSE ChannelClose; + + /* Generate handle. */ + ChannelClose.ulChannelHndl = cOCT6100_HNDL_TAG_CHANNEL | (pChanEntry->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + /* Call serialized close channel function. */ + ulResult = Oct6100ChannelCloseSer( f_pApiInstance, &ChannelClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + + /* Close all TSI connections. */ + if ( f_pFreeResources->fFreeTsiConnections == TRUE ) + { + tPOCT6100_API_TSI_CNCT pTsiCnct; + tOCT6100_TSI_CNCT_CLOSE TsiCnctClose; + + Oct6100TsiCnctCloseDef( &TsiCnctClose ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxTsiCncts; i ++ ) + { + /* Obtain a pointer to the TSI connection list entry. */ + mOCT6100_GET_TSI_CNCT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pTsiCnct, i ); + + if ( pTsiCnct->fReserved == TRUE ) + { + TsiCnctClose.ulTsiCnctHndl = cOCT6100_HNDL_TAG_TSI_CNCT | (pTsiCnct->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100TsiCnctCloseSer( f_pApiInstance, &TsiCnctClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Close all conference bridges. */ + if ( f_pFreeResources->fFreeConferenceBridges == TRUE ) + { + tPOCT6100_API_CONF_BRIDGE pConfBridge; + tOCT6100_CONF_BRIDGE_CLOSE ConfBridgeClose; + + Oct6100ConfBridgeCloseDef( &ConfBridgeClose ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxConfBridges; i ++ ) + { + /* Obtain a pointer to the conference bridge's list entry. */ + mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pConfBridge, i ); + + if ( pConfBridge->fReserved == TRUE ) + { + ConfBridgeClose.ulConfBridgeHndl = cOCT6100_HNDL_TAG_CONF_BRIDGE | (pConfBridge->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100ConfBridgeCloseSer( f_pApiInstance, &ConfBridgeClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Free all playout buffers loaded in external memory. */ + if ( f_pFreeResources->fFreePlayoutBuffers == TRUE ) + { + tPOCT6100_API_BUFFER pBuffer; + tOCT6100_BUFFER_UNLOAD BufferUnload; + + Oct6100BufferPlayoutUnloadDef( &BufferUnload ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxPlayoutBuffers; i ++ ) + { + + + /* Obtain a pointer to the buffer list entry. */ + mOCT6100_GET_BUFFER_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBuffer, i ); + + if ( pBuffer->fReserved == TRUE ) + { + BufferUnload.ulBufferIndex = i; + ulResult = Oct6100BufferUnloadSer( f_pApiInstance, &BufferUnload, TRUE ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + + /* Close all phasing TSSTs. */ + if ( f_pFreeResources->fFreePhasingTssts == TRUE ) + { + tPOCT6100_API_PHASING_TSST pPhasingTsst; + tOCT6100_PHASING_TSST_CLOSE PhasingTsstClose; + + Oct6100PhasingTsstCloseDef( &PhasingTsstClose ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxPhasingTssts; i ++ ) + { + mOCT6100_GET_PHASING_TSST_ENTRY_PNT( pSharedInfo, pPhasingTsst, i ); + + if ( pPhasingTsst->fReserved == TRUE ) + { + PhasingTsstClose.ulPhasingTsstHndl = cOCT6100_HNDL_TAG_PHASING_TSST | (pPhasingTsst->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100PhasingTsstCloseSer( f_pApiInstance, &PhasingTsstClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + /* Close all ADPCM channels. */ + if ( f_pFreeResources->fFreeAdpcmChannels == TRUE ) + { + tPOCT6100_API_ADPCM_CHAN pAdpcmChannel; + tOCT6100_ADPCM_CHAN_CLOSE AdpcmChanClose; + + Oct6100AdpcmChanCloseDef( &AdpcmChanClose ); + + for ( i = 0; i < pSharedInfo->ChipConfig.usMaxAdpcmChannels; i ++ ) + { + mOCT6100_GET_ADPCM_CHAN_ENTRY_PNT( pSharedInfo, pAdpcmChannel, i ); + if ( pAdpcmChannel->fReserved == TRUE ) + { + AdpcmChanClose.ulChanHndl = cOCT6100_HNDL_TAG_ADPCM_CHANNEL | (pAdpcmChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | i; + + ulResult = Oct6100AdpcmChanCloseSer( f_pApiInstance, &AdpcmChanClose ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + } + } + + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ProductionBistSer + +Description: This function returns the instantaneous production BIST status. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pProductionBist Pointer to user structure in which BIST status will + be returned. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ProductionBistSer( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN OUT tPOCT6100_PRODUCTION_BIST f_pProductionBist ) +{ + UINT32 ulCalculatedCrc = cOCT6100_INVALID_VALUE; + UINT32 ulResult; + UINT32 ulLoopCnt = 0x0; + UINT32 i = 1; + UINT32 ulTotalElements = 4; + UINT32 ulReadAddress = cOCT6100_POUCH_BASE; + UINT32 aulMessage[ 5 ]; + + /* Check if the production bist has been activated. */ + if ( f_pApiInstance->pSharedInfo->ChipConfig.fEnableProductionBist == FALSE ) + return cOCT6100_ERR_PRODUCTION_BIST_DISABLED; + + f_pProductionBist->ulCurrentAddress = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulCurrentLoop = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulCurrentTest = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulFailedAddress = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulReadValue = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulExpectedValue = cOCT6100_INVALID_VALUE; + f_pProductionBist->ulBistStatus = cOCT6100_BIST_IN_PROGRESS; + + /* The API knows that the firmware might be writing a status event. */ + /* The firmware does write a status event every 200ms (approximately). */ + /* So the status is read a couple of times to make sure an event was not read while */ + /* it was written. */ + while ( ulLoopCnt != 2 ) + { + /* Read the BIST status in the external memory. */ + for ( i = 0; i < ulTotalElements + 1; i ++ ) + { + ulResult = Oct6100ApiReadDword( f_pApiInstance, ulReadAddress + i * 4, &aulMessage[ i ] ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + } + + /* Calculate the CRC of this message. */ + ulResult = Oct6100ApiProductionCrc( f_pApiInstance, aulMessage, ulTotalElements, &ulCalculatedCrc ); + if ( ulResult != cOCT6100_ERR_OK ) + return ulResult; + + /* If the CRCs do match, break off the while. We have a valid status event. */ + if ( aulMessage[ i - 1 ] == ulCalculatedCrc ) + break; + + ulLoopCnt++; + } + + /* Check if the CRC matches */ + if ( aulMessage[ i - 1 ] != ulCalculatedCrc ) + { + /* Well, the exchange memory at the base of the external memory is corrupted. */ + /* Something very basic is not working correctly with this chip! */ + f_pProductionBist->ulBistStatus = cOCT6100_BIST_STATUS_CRC_FAILED; + } + else + { + /* Check for problems. */ + switch ( aulMessage[ 0 ] & 0xFFFF ) + { + case ( 0x2 ): + + /* The initial configuration failed. */ + f_pProductionBist->ulBistStatus = cOCT6100_BIST_CONFIGURATION_FAILED; + break; + + case ( 0x1 ): + + /* A memory location failed. Return useful information to the user. */ + f_pProductionBist->ulBistStatus = cOCT6100_BIST_MEMORY_FAILED; + + f_pProductionBist->ulFailedAddress = ( aulMessage[ 1 ] & ( ~0x80000000 ) ) + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + f_pProductionBist->ulReadValue = aulMessage[ 2 ]; + f_pProductionBist->ulExpectedValue = aulMessage[ 3 ]; + break; + + case ( 0xFFFF ): + + /* Bist is completed! */ + f_pProductionBist->ulBistStatus = cOCT6100_BIST_SUCCESS; + break; + + default: + /* Bist is in progress. All seems to be working fine up to now. */ + + /* Return progress status. */ + f_pProductionBist->ulCurrentAddress = ( aulMessage[ 1 ] & ( ~0x80000000 ) ) + cOCT6100_EXTERNAL_MEM_BASE_ADDRESS; + f_pProductionBist->ulCurrentTest = aulMessage[ 2 ]; + f_pProductionBist->ulCurrentLoop = aulMessage[ 3 ]; + break; + } + } + + return cOCT6100_ERR_OK; +} + + +/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\ + +Function: Oct6100ApiProductionCrc + +Description: This function calculates the crc for a production BIST + message. + +------------------------------------------------------------------------------- +| Argument | Description +------------------------------------------------------------------------------- +f_pApiInstance Pointer to API instance. This memory is used to keep + the present state of the chip and all its resources. + +f_pulMessage Message to be exchanged with the firmware. The CRC + will be calculated on this. +f_ulMessageLength Length of the message to be exchanged. This value + does not include the CRC value at the end +f_pulCrcResult Resulting calculated CRC value. + +\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ +UINT32 Oct6100ApiProductionCrc( + IN OUT tPOCT6100_INSTANCE_API f_pApiInstance, + IN PUINT32 f_pulMessage, + IN UINT32 f_ulMessageLength, + OUT PUINT32 f_pulCrcResult ) +{ + UINT32 ulWidth = 32; + UINT32 ulKey, i, j; + UINT32 ulRemainder = 0; + + /* CRC the message. */ + ulRemainder = f_pulMessage[ f_ulMessageLength - 1 ]; + for ( j = f_ulMessageLength - 1; j != 0xFFFFFFFF ; j-- ) + { + for ( i = 0; i < ulWidth; i++ ) + { + if ( ( ( ulRemainder >> 0x1F ) & 0x1 ) == 0x1 ) + { + /* Division is by something meaningful */ + ulKey = 0x8765DCBA; + } + else + { + /* Remainder is less than our divisor */ + ulKey = 0; + } + ulRemainder = ulRemainder ^ ulKey; + + ulRemainder = ulRemainder << 1; + if ( j != 0 ) + { + ulRemainder = ulRemainder | ( ( f_pulMessage[ j - 1 ] ) >> ( 0x1F - i ) ); + } + } + } + + *f_pulCrcResult = ulRemainder; + + return cOCT6100_ERR_OK; +} -- cgit v1.2.3