1279 lines
52 KiB
C
1279 lines
52 KiB
C
|
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|
||
|
|
||
|
File: oct6100_debug.c
|
||
|
|
||
|
Copyright (c) 2001-2007 Octasic Inc.
|
||
|
|
||
|
Description:
|
||
|
|
||
|
This file contains functions used to debug the OCT6100.
|
||
|
|
||
|
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-PR49 $
|
||
|
|
||
|
$Octasic_Revision: 65 $
|
||
|
|
||
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
||
|
|
||
|
|
||
|
/***************************** INCLUDE FILES *******************************/
|
||
|
|
||
|
#include "octdef.h"
|
||
|
|
||
|
#include "oct6100api/oct6100_defines.h"
|
||
|
#include "oct6100api/oct6100_errors.h"
|
||
|
#include "oct6100api/oct6100_apiud.h"
|
||
|
|
||
|
#include "oct6100api/oct6100_apiud.h"
|
||
|
#include "oct6100api/oct6100_tlv_inst.h"
|
||
|
#include "oct6100api/oct6100_chip_open_inst.h"
|
||
|
#include "oct6100api/oct6100_chip_stats_inst.h"
|
||
|
#include "oct6100api/oct6100_interrupts_inst.h"
|
||
|
#include "oct6100api/oct6100_remote_debug_inst.h"
|
||
|
#include "oct6100api/oct6100_debug_inst.h"
|
||
|
#include "oct6100api/oct6100_api_inst.h"
|
||
|
#include "oct6100api/oct6100_channel_inst.h"
|
||
|
|
||
|
#include "oct6100api/oct6100_interrupts_pub.h"
|
||
|
#include "oct6100api/oct6100_chip_open_pub.h"
|
||
|
#include "oct6100api/oct6100_channel_pub.h"
|
||
|
#include "oct6100api/oct6100_debug_pub.h"
|
||
|
|
||
|
#include "oct6100_chip_open_priv.h"
|
||
|
#include "oct6100_channel_priv.h"
|
||
|
#include "oct6100_miscellaneous_priv.h"
|
||
|
#include "oct6100_memory_priv.h"
|
||
|
#include "oct6100_debug_priv.h"
|
||
|
#include "oct6100_version.h"
|
||
|
|
||
|
|
||
|
/**************************** PUBLIC FUNCTIONS ****************************/
|
||
|
|
||
|
|
||
|
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|
||
|
|
||
|
Function: Oct6100DebugSelectChannel
|
||
|
|
||
|
Description: This function sets the current 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.
|
||
|
|
||
|
f_pSelectDebugChan Pointer to select debug channel structure.
|
||
|
|
||
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
||
|
#if !SKIP_Oct6100DebugSelectChannelDef
|
||
|
UINT32 Oct6100DebugSelectChannelDef(
|
||
|
tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan )
|
||
|
{
|
||
|
f_pSelectDebugChan->ulChannelHndl = cOCT6100_INVALID_VALUE;
|
||
|
|
||
|
return cOCT6100_ERR_OK;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if !SKIP_Oct6100DebugSelectChannel
|
||
|
UINT32 Oct6100DebugSelectChannel(
|
||
|
tPOCT6100_INSTANCE_API f_pApiInstance,
|
||
|
tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan )
|
||
|
{
|
||
|
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 = Oct6100DebugSelectChannelSer( f_pApiInstance, f_pSelectDebugChan, TRUE );
|
||
|
}
|
||
|
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;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|
||
|
|
||
|
Function: Oct6100DebugGetData
|
||
|
|
||
|
Description: This function retrieves the last recorded debug data.
|
||
|
|
||
|
-------------------------------------------------------------------------------
|
||
|
| 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_pGetData Pointer to debug get data structure.
|
||
|
|
||
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
||
|
#if !SKIP_Oct6100DebugGetDataDef
|
||
|
UINT32 Oct6100DebugGetDataDef(
|
||
|
tPOCT6100_DEBUG_GET_DATA f_pGetData )
|
||
|
{
|
||
|
f_pGetData->ulGetDataMode = cOCT6100_DEBUG_GET_DATA_MODE_120S_LITE;
|
||
|
f_pGetData->ulGetDataContent = cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE;
|
||
|
f_pGetData->ulRemainingNumBytes = cOCT6100_INVALID_VALUE;
|
||
|
f_pGetData->ulTotalNumBytes = cOCT6100_INVALID_VALUE;
|
||
|
f_pGetData->ulMaxBytes = cOCT6100_INVALID_VALUE;
|
||
|
f_pGetData->ulValidNumBytes = cOCT6100_INVALID_VALUE;
|
||
|
f_pGetData->pbyData = NULL;
|
||
|
|
||
|
return cOCT6100_ERR_OK;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#if !SKIP_Oct6100DebugGetData
|
||
|
UINT32 Oct6100DebugGetData(
|
||
|
tPOCT6100_INSTANCE_API f_pApiInstance,
|
||
|
tPOCT6100_DEBUG_GET_DATA f_pGetData )
|
||
|
{
|
||
|
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 = Oct6100DebugGetDataSer( f_pApiInstance, f_pGetData );
|
||
|
}
|
||
|
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;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/**************************** PRIVATE FUNCTIONS ****************************/
|
||
|
|
||
|
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|
||
|
|
||
|
Function: Oct6100DebugSelectChannelSer
|
||
|
|
||
|
Description: This function sets the 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.
|
||
|
|
||
|
f_pSelectDebugChan Pointer to a tOCT6100_DEBUG_SELECT_CHANNEL structure.
|
||
|
f_fCheckChannelRecording Check if channel recording is enabled or not.
|
||
|
|
||
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
||
|
#if !SKIP_Oct6100DebugSelectChannelSer
|
||
|
UINT32 Oct6100DebugSelectChannelSer(
|
||
|
IN OUT tPOCT6100_INSTANCE_API f_pApiInstance,
|
||
|
IN tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan,
|
||
|
IN BOOL f_fCheckChannelRecording )
|
||
|
{
|
||
|
tPOCT6100_SHARED_INFO pSharedInfo;
|
||
|
tPOCT6100_API_CHANNEL pChanEntry = NULL;
|
||
|
tPOCT6100_API_CHANNEL pTempChanEntry;
|
||
|
tOCT6100_CHANNEL_OPEN TempChanOpen;
|
||
|
tOCT6100_WRITE_BURST_PARAMS BurstParams;
|
||
|
UINT16 usChanIndex = 0;
|
||
|
UINT32 ulEntryOpenCnt;
|
||
|
UINT16 ausWriteData[ 2 ];
|
||
|
UINT32 ulResult;
|
||
|
|
||
|
/* Get local pointer(s). */
|
||
|
pSharedInfo = f_pApiInstance->pSharedInfo;
|
||
|
|
||
|
BurstParams.pProcessContext = f_pApiInstance->pProcessContext;
|
||
|
|
||
|
BurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
|
||
|
BurstParams.pusWriteData = ausWriteData;
|
||
|
|
||
|
/* First release the resources reserved for the channel that was previously debugged. */
|
||
|
if ( pSharedInfo->DebugInfo.usCurrentDebugChanIndex != cOCT6100_INVALID_INDEX &&
|
||
|
pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE )
|
||
|
{
|
||
|
/*=======================================================================*/
|
||
|
/* Get a pointer to the channel's list entry. */
|
||
|
|
||
|
mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pTempChanEntry, pSharedInfo->DebugInfo.usCurrentDebugChanIndex )
|
||
|
|
||
|
/* Release the extra TSI memory entry and reprogram the TSST control memory if required. */
|
||
|
if ( pTempChanEntry->usExtraSinTsiDependencyCnt >= 1 )
|
||
|
{
|
||
|
/*=======================================================================*/
|
||
|
/* Clear memcpy operations. */
|
||
|
|
||
|
BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE );
|
||
|
BurstParams.ulWriteLength = 2;
|
||
|
|
||
|
ausWriteData[ 0 ] = cOCT6100_MIXER_CONTROL_MEM_NO_OP;
|
||
|
ausWriteData[ 1 ] = 0x0;
|
||
|
|
||
|
mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
|
||
|
BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordSinEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE );
|
||
|
|
||
|
mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
|
||
|
/*=======================================================================*/
|
||
|
|
||
|
/* If we are the last dependency using the extra Sin TSI, release it */
|
||
|
if ( pTempChanEntry->usExtraSinTsiDependencyCnt == 1 )
|
||
|
{
|
||
|
ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pTempChanEntry->usExtraSinTsiMemIndex );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
|
||
|
/* Do not forget to reprogram the TSST control memory. */
|
||
|
if ( pTempChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX )
|
||
|
{
|
||
|
ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance,
|
||
|
pTempChanEntry->usSinTsstIndex,
|
||
|
pTempChanEntry->usSinSoutTsiMemIndex,
|
||
|
pTempChanEntry->TdmConfig.bySinPcmLaw );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
}
|
||
|
pTempChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX;
|
||
|
|
||
|
/* XXX: What about the silence TSI usSinSilenceEventIndex ?? */
|
||
|
}
|
||
|
|
||
|
pTempChanEntry->usExtraSinTsiDependencyCnt--;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Set the new parameters. */
|
||
|
if ( f_pSelectDebugChan->ulChannelHndl != cOCT6100_INVALID_HANDLE )
|
||
|
{
|
||
|
/* Check the provided handle. */
|
||
|
if ( (f_pSelectDebugChan->ulChannelHndl & cOCT6100_HNDL_TAG_MASK) != cOCT6100_HNDL_TAG_CHANNEL )
|
||
|
return cOCT6100_ERR_DEBUG_CHANNEL_INVALID_HANDLE;
|
||
|
|
||
|
usChanIndex = (UINT16)( f_pSelectDebugChan->ulChannelHndl & cOCT6100_HNDL_INDEX_MASK );
|
||
|
if ( usChanIndex >= pSharedInfo->ChipConfig.usMaxChannels )
|
||
|
return cOCT6100_ERR_DEBUG_CHANNEL_INVALID_HANDLE;
|
||
|
|
||
|
if ( f_fCheckChannelRecording == TRUE )
|
||
|
{
|
||
|
if ( pSharedInfo->ChipConfig.fEnableChannelRecording == FALSE )
|
||
|
return cOCT6100_ERR_DEBUG_CHANNEL_RECORDING_DISABLED;
|
||
|
}
|
||
|
|
||
|
/*=======================================================================*/
|
||
|
/* Get a pointer to the channel's list entry. */
|
||
|
|
||
|
mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, usChanIndex );
|
||
|
|
||
|
/* Extract the entry open count from the provided handle. */
|
||
|
ulEntryOpenCnt = ( f_pSelectDebugChan->ulChannelHndl >> cOCT6100_ENTRY_OPEN_CNT_SHIFT) & cOCT6100_ENTRY_OPEN_CNT_MASK;
|
||
|
|
||
|
/* Check for errors. */
|
||
|
if ( pChanEntry->fReserved != TRUE )
|
||
|
return cOCT6100_ERR_CHANNEL_NOT_OPEN;
|
||
|
if ( ulEntryOpenCnt != pChanEntry->byEntryOpenCnt )
|
||
|
return cOCT6100_ERR_CHANNEL_INVALID_HANDLE;
|
||
|
|
||
|
/*=======================================================================*/
|
||
|
|
||
|
/* First program the mixer entry if the user wants to record. */
|
||
|
/* Check if the API needs to reserve an extra TSI memory to load the SIN signal. */
|
||
|
if ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE )
|
||
|
{
|
||
|
/* Reserve the extra Sin TSI memory if it was not already reserved. */
|
||
|
if ( pChanEntry->usExtraSinTsiMemIndex == cOCT6100_INVALID_INDEX )
|
||
|
{
|
||
|
ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, &pChanEntry->usExtraSinTsiMemIndex );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
|
||
|
/* Reprogram the TSST control memory accordingly. */
|
||
|
if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX )
|
||
|
{
|
||
|
ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance,
|
||
|
pChanEntry->usSinTsstIndex,
|
||
|
pChanEntry->usExtraSinTsiMemIndex,
|
||
|
pChanEntry->TdmConfig.bySinPcmLaw );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
}
|
||
|
|
||
|
/* XXX: What about the silence TSI usSinSilenceEventIndex ?? */
|
||
|
}
|
||
|
|
||
|
|
||
|
/*=======================================================================*/
|
||
|
/* Program the Sout Copy event. */
|
||
|
BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordCopyEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE );
|
||
|
BurstParams.ulWriteLength = 2;
|
||
|
|
||
|
ausWriteData[ 0 ] = cOCT6100_MIXER_CONTROL_MEM_COPY;
|
||
|
ausWriteData[ 0 ] |= pChanEntry->usSinSoutTsiMemIndex;
|
||
|
ausWriteData[ 0 ] |= pChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET;
|
||
|
ausWriteData[ 1 ] = (UINT16)( pSharedInfo->DebugInfo.usRecordRinRoutTsiMemIndex );
|
||
|
|
||
|
mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
/*=======================================================================*/
|
||
|
|
||
|
/*=======================================================================*/
|
||
|
/* Program the Sin copy event. */
|
||
|
BurstParams.ulWriteAddress = cOCT6100_MIXER_CONTROL_MEM_BASE + ( pSharedInfo->MixerInfo.usRecordSinEventIndex * cOCT6100_MIXER_CONTROL_MEM_ENTRY_SIZE );
|
||
|
BurstParams.ulWriteLength = 2;
|
||
|
|
||
|
ausWriteData[ 0 ] = cOCT6100_MIXER_CONTROL_MEM_COPY;
|
||
|
ausWriteData[ 0 ] |= pChanEntry->usExtraSinTsiMemIndex;
|
||
|
ausWriteData[ 0 ] |= pChanEntry->TdmConfig.bySinPcmLaw << cOCT6100_MIXER_CONTROL_MEM_LAW_OFFSET;
|
||
|
ausWriteData[ 1 ] = pChanEntry->usSinSoutTsiMemIndex;
|
||
|
|
||
|
mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
/*=======================================================================*/
|
||
|
|
||
|
pChanEntry->usExtraSinTsiDependencyCnt++;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* Set the index to invalid to deactivate the recording. */
|
||
|
usChanIndex = cOCT6100_INVALID_INDEX;
|
||
|
}
|
||
|
|
||
|
/* Set law of newly selected hot channel. */
|
||
|
if ( ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE )
|
||
|
&& ( f_pSelectDebugChan->ulChannelHndl != cOCT6100_INVALID_HANDLE )
|
||
|
&& ( pChanEntry != NULL ) )
|
||
|
{
|
||
|
/* Set the PCM law of the debug channel. */
|
||
|
/* Let's program the channel memory. */
|
||
|
Oct6100ChannelOpenDef( &TempChanOpen );
|
||
|
|
||
|
TempChanOpen.ulEchoOperationMode = cOCT6100_ECHO_OP_MODE_HT_RESET; /* Activate the channel. */
|
||
|
TempChanOpen.VqeConfig.fEnableNlp = FALSE;
|
||
|
TempChanOpen.VqeConfig.ulComfortNoiseMode = cOCT6100_COMFORT_NOISE_NORMAL;
|
||
|
TempChanOpen.VqeConfig.fSinDcOffsetRemoval = FALSE;
|
||
|
TempChanOpen.VqeConfig.fRinDcOffsetRemoval = FALSE;
|
||
|
TempChanOpen.VqeConfig.lDefaultErlDb = 0;
|
||
|
|
||
|
/* Use the law of the channel being recorded. */
|
||
|
TempChanOpen.TdmConfig.ulRinPcmLaw = pChanEntry->TdmConfig.byRinPcmLaw;
|
||
|
TempChanOpen.TdmConfig.ulSinPcmLaw = pChanEntry->TdmConfig.bySinPcmLaw;
|
||
|
TempChanOpen.TdmConfig.ulRoutPcmLaw = pChanEntry->TdmConfig.byRoutPcmLaw;
|
||
|
TempChanOpen.TdmConfig.ulSoutPcmLaw = pChanEntry->TdmConfig.bySoutPcmLaw;
|
||
|
|
||
|
ulResult = Oct6100ApiWriteDebugChanMemory( f_pApiInstance,
|
||
|
&TempChanOpen.TdmConfig,
|
||
|
&TempChanOpen.VqeConfig,
|
||
|
&TempChanOpen,
|
||
|
pSharedInfo->DebugInfo.usRecordChanIndex,
|
||
|
pSharedInfo->DebugInfo.usRecordMemIndex,
|
||
|
pSharedInfo->DebugInfo.usRecordRinRoutTsiMemIndex,
|
||
|
pSharedInfo->DebugInfo.usRecordSinSoutTsiMemIndex );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
}
|
||
|
|
||
|
ausWriteData[ 0 ] = 0x0;
|
||
|
ausWriteData[ 1 ] = (UINT16)(( usChanIndex >> 0) & 0xFFFF);
|
||
|
|
||
|
/* Write the channel number into the Matrix hot channel field.*/
|
||
|
BurstParams.ulWriteAddress = pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress;
|
||
|
BurstParams.pusWriteData = ausWriteData;
|
||
|
BurstParams.ulWriteLength = 2;
|
||
|
|
||
|
mOCT6100_DRIVER_WRITE_BURST_API( BurstParams, ulResult );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
|
||
|
pSharedInfo->DebugInfo.usCurrentDebugChanIndex = usChanIndex;
|
||
|
|
||
|
/* Cancel data dump request, if there was one. */
|
||
|
pSharedInfo->DebugInfo.fDebugDataBeingDumped = FALSE;
|
||
|
pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes = cOCT6100_INVALID_VALUE;
|
||
|
|
||
|
/* Call from remote client. */
|
||
|
if ( f_fCheckChannelRecording == FALSE )
|
||
|
{
|
||
|
/* If the user has not activated recording, let the remote client know. */
|
||
|
if ( pSharedInfo->ChipConfig.fEnableChannelRecording == FALSE )
|
||
|
return cOCT6100_ERR_DEBUG_RC_CHANNEL_RECORDING_DISABLED;
|
||
|
}
|
||
|
|
||
|
return cOCT6100_ERR_OK;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
|
||
|
|
||
|
Function: Oct6100DebugGetDataSer
|
||
|
|
||
|
Description: This function retrieves the latest recorded debug data.
|
||
|
|
||
|
-------------------------------------------------------------------------------
|
||
|
| 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_pGetData Pointer to a tOCT6100_DEBUG_GET_DATA structure.
|
||
|
|
||
|
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
|
||
|
#if !SKIP_Oct6100DebugGetDataSer
|
||
|
UINT32 Oct6100DebugGetDataSer(
|
||
|
IN OUT tPOCT6100_INSTANCE_API f_pApiInstance,
|
||
|
IN OUT tPOCT6100_DEBUG_GET_DATA f_pGetData )
|
||
|
{
|
||
|
|
||
|
tPOCT6100_SHARED_INFO pSharedInfo;
|
||
|
tPOCT6100_API_CHANNEL pChanEntry = NULL;
|
||
|
tOCT6100_READ_PARAMS ReadParams;
|
||
|
tOCT6100_WRITE_PARAMS WriteParams;
|
||
|
tOCT6100_READ_BURST_PARAMS ReadBurstParams;
|
||
|
tOCT6100_WRITE_BURST_PARAMS WriteBurstParams;
|
||
|
|
||
|
UINT16 ausWriteData[ 2 ];
|
||
|
UINT16 usReadData;
|
||
|
UINT16 usDebugEventReadPtr;
|
||
|
UINT16 usTempNumEvents;
|
||
|
|
||
|
UINT32 ulResult;
|
||
|
UINT32 ulToneEventIndex;
|
||
|
UINT32 ulReadPointer;
|
||
|
UINT32 ulUserBufWriteIndex = 0;
|
||
|
UINT32 ulTimestamp;
|
||
|
UINT32 ulDebugEventIndex = 0;
|
||
|
UINT32 ulStreamIndex;
|
||
|
UINT32 ulPcmSampleIndex;
|
||
|
UINT32 ulNumAfEvents;
|
||
|
UINT32 ulNumReads = 0;
|
||
|
UINT32 ulTempIndex;
|
||
|
UINT32 ulCopyIndex;
|
||
|
UINT32 ulFeatureBytesOffset;
|
||
|
UINT32 ulFeatureBitOffset;
|
||
|
UINT32 ulFeatureFieldLength;
|
||
|
UINT32 ulStreamIndexMin;
|
||
|
UINT32 ulStreamIndexMax;
|
||
|
UINT32 ulTempData;
|
||
|
UINT32 ulMask;
|
||
|
BOOL fResetRemainingDataFlag = FALSE;
|
||
|
|
||
|
/* Get local pointer(s). */
|
||
|
pSharedInfo = f_pApiInstance->pSharedInfo;
|
||
|
|
||
|
ReadBurstParams.pProcessContext = f_pApiInstance->pProcessContext;
|
||
|
|
||
|
ReadBurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
|
||
|
|
||
|
ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
|
||
|
|
||
|
ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
|
||
|
|
||
|
WriteBurstParams.pProcessContext = f_pApiInstance->pProcessContext;
|
||
|
|
||
|
WriteBurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
|
||
|
|
||
|
WriteParams.pProcessContext = f_pApiInstance->pProcessContext;
|
||
|
|
||
|
WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
|
||
|
|
||
|
/* Check all user parameters. */
|
||
|
|
||
|
/* Check if channel recording is enabled. */
|
||
|
if ( pSharedInfo->ChipConfig.fEnableChannelRecording == FALSE )
|
||
|
return cOCT6100_ERR_DEBUG_CHANNEL_RECORDING_DISABLED;
|
||
|
|
||
|
/* Check if a current debugging channel has been selected. */
|
||
|
/* If not, the user has not yet called Oct6100DebugSelectChannel. */
|
||
|
if ( pSharedInfo->DebugInfo.usCurrentDebugChanIndex == cOCT6100_INVALID_INDEX )
|
||
|
return cOCT6100_ERR_DEBUG_RECORD_NO_CHAN_SELECTED;
|
||
|
|
||
|
/* Check that the user supplied a valid max bytes value. */
|
||
|
if ( f_pGetData->ulMaxBytes == cOCT6100_INVALID_VALUE )
|
||
|
return cOCT6100_ERR_DEBUG_GET_DATA_MAX_BYTES;
|
||
|
|
||
|
/* Data buffer must be aligned on 1024 bytes. */
|
||
|
if ( ( f_pGetData->ulMaxBytes % 1024 ) != 0 )
|
||
|
return cOCT6100_ERR_DEBUG_GET_DATA_MAX_BYTES;
|
||
|
|
||
|
/* Check that the user provided the required memory to transfer the information. */
|
||
|
if ( f_pGetData->pbyData == NULL )
|
||
|
return cOCT6100_ERR_DEBUG_GET_DATA_PTR_INVALID;
|
||
|
|
||
|
/* Check dump type. */
|
||
|
if ( ( f_pGetData->ulGetDataMode != cOCT6100_DEBUG_GET_DATA_MODE_16S_LITE )
|
||
|
&& ( f_pGetData->ulGetDataMode != cOCT6100_DEBUG_GET_DATA_MODE_120S_LITE )
|
||
|
&& ( f_pGetData->ulGetDataMode != cOCT6100_DEBUG_GET_DATA_MODE_16S )
|
||
|
&& ( f_pGetData->ulGetDataMode != cOCT6100_DEBUG_GET_DATA_MODE_120S ) )
|
||
|
return cOCT6100_ERR_DEBUG_GET_DATA_MODE;
|
||
|
|
||
|
/* Check dump content. */
|
||
|
if ( ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE )
|
||
|
&& ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_RIN_PCM )
|
||
|
&& ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_SIN_PCM )
|
||
|
&& ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_SOUT_PCM ) )
|
||
|
return cOCT6100_ERR_DEBUG_GET_DATA_CONTENT;
|
||
|
|
||
|
/* Check if can accomodate the 120 seconds dump. */
|
||
|
if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S_LITE )
|
||
|
|| ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) )
|
||
|
{
|
||
|
if ( pSharedInfo->DebugInfo.ulDebugEventSize != 0x100 )
|
||
|
return cOCT6100_ERR_NOT_SUPPORTED_DEBUG_DATA_MODE_120S;
|
||
|
}
|
||
|
|
||
|
mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, pSharedInfo->DebugInfo.usCurrentDebugChanIndex )
|
||
|
|
||
|
/* Lets go dump the requested data. */
|
||
|
|
||
|
usDebugEventReadPtr = 0;
|
||
|
|
||
|
/* Check if this is the first time this function is called since the hot channel was set. */
|
||
|
if ( pSharedInfo->DebugInfo.fDebugDataBeingDumped == FALSE )
|
||
|
{
|
||
|
/* Check that the channel is not in POWER_DOWN. When the channel is in POWER_DOWN, */
|
||
|
/* the debug events are not recorded correctly in external memory. */
|
||
|
if ( pChanEntry->byEchoOperationMode == cOCT6100_ECHO_OP_MODE_POWER_DOWN )
|
||
|
return cOCT6100_ERR_DEBUG_CHANNEL_IN_POWER_DOWN;
|
||
|
|
||
|
pSharedInfo->DebugInfo.fDebugDataBeingDumped = TRUE;
|
||
|
|
||
|
/* Flag the hot channel that it must stop recording. The data is being transfered. */
|
||
|
/* This also tells the remote client not to do anything right now. */
|
||
|
|
||
|
ReadBurstParams.ulReadAddress = pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress;
|
||
|
ReadBurstParams.ulReadLength = 2;
|
||
|
ReadBurstParams.pusReadData = pSharedInfo->DebugInfo.ausHotChannelData;
|
||
|
|
||
|
mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
|
||
|
WriteBurstParams.pusWriteData = ausWriteData;
|
||
|
WriteBurstParams.ulWriteAddress = pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress;
|
||
|
WriteBurstParams.ulWriteLength = 2;
|
||
|
|
||
|
WriteBurstParams.pusWriteData[ 0 ] = 0xFFFF;
|
||
|
WriteBurstParams.pusWriteData[ 1 ] = 0xFFFF;
|
||
|
|
||
|
mOCT6100_DRIVER_WRITE_BURST_API( WriteBurstParams, ulResult );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
|
||
|
/* Get the maximum number of events this firmware supports from the TLVs. */
|
||
|
pSharedInfo->DebugInfo.usMatrixCBMask = (UINT16)( pSharedInfo->DebugInfo.ulDebugEventSize & 0xFFFF );
|
||
|
pSharedInfo->DebugInfo.usMatrixCBMask -= 1;
|
||
|
|
||
|
/* Find out the chip log write pointer. */
|
||
|
|
||
|
/* Now get the current write pointer for matrix events. */
|
||
|
ReadParams.pusReadData = &pSharedInfo->DebugInfo.usChipDebugEventWritePtr;
|
||
|
ReadParams.ulReadAddress = pSharedInfo->DebugInfo.ulMatrixWpBaseAddress + 2;
|
||
|
|
||
|
mOCT6100_DRIVER_READ_API( ReadParams, ulResult );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
|
||
|
ReadParams.pusReadData = &usReadData;
|
||
|
|
||
|
/* This write pointer might have wrapped, but we don't know for sure. */
|
||
|
/* To be confident, the chip frame timestamp is read. */
|
||
|
ReadParams.ulReadAddress = pSharedInfo->DebugInfo.ulMatrixTimestampBaseAddress;
|
||
|
|
||
|
mOCT6100_DRIVER_READ_API( ReadParams, ulResult );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
|
||
|
ulTimestamp = usReadData << 16;
|
||
|
|
||
|
ReadParams.ulReadAddress += 2;
|
||
|
|
||
|
mOCT6100_DRIVER_READ_API( ReadParams, ulResult );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
|
||
|
ulTimestamp |= usReadData;
|
||
|
|
||
|
ulTimestamp >>= 12; /* TDM time for 1 event (512 ms) */
|
||
|
|
||
|
/* There is a probability here (once very 6.2 days) that the timestamp is close */
|
||
|
/* to 0, because it has wrapped. But still, we need a way to workaround the highly */
|
||
|
/* occuring case of the chip just being opened. This will fix this problem. */
|
||
|
if ( ulTimestamp < (UINT32)( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) )
|
||
|
{
|
||
|
if ( pSharedInfo->DebugInfo.usChipDebugEventWritePtr >= 2 )
|
||
|
{
|
||
|
/* Must trash the first 2 events. The chip is not yet ready. */
|
||
|
pSharedInfo->DebugInfo.usNumEvents = (UINT16)( pSharedInfo->DebugInfo.usChipDebugEventWritePtr - 2 );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pSharedInfo->DebugInfo.usNumEvents = 0x0;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pSharedInfo->DebugInfo.usNumEvents = (UINT16)( pSharedInfo->DebugInfo.usMatrixCBMask + 1 );
|
||
|
|
||
|
/* Account for event being created right now while the chip is running. */
|
||
|
/* The event at the write pointer will be discarded. */
|
||
|
if ( pSharedInfo->DebugInfo.usNumEvents > 0 )
|
||
|
pSharedInfo->DebugInfo.usNumEvents--;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* If the user only requested the last 16 seconds, cap the number of events. */
|
||
|
if ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S
|
||
|
|| f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S_LITE )
|
||
|
{
|
||
|
/* x events to get the last 16 seconds. */
|
||
|
if ( pSharedInfo->DebugInfo.usNumEvents > ( 16000 / ( pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize / 8 ) ) )
|
||
|
pSharedInfo->DebugInfo.usNumEvents = (UINT16)( ( 16000 / ( pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize / 8 ) ) & 0xFFFF );
|
||
|
}
|
||
|
|
||
|
/* Make sure that all the events are pertaining to the current hot channel. */
|
||
|
/* Calculate the event read pointer. */
|
||
|
ulReadPointer = ( ( pSharedInfo->DebugInfo.usChipDebugEventWritePtr - pSharedInfo->DebugInfo.usNumEvents ) & pSharedInfo->DebugInfo.usMatrixCBMask ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize;
|
||
|
ulReadPointer %= ( ( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize );
|
||
|
|
||
|
/* Travel through the events and throw away the bad events. */
|
||
|
usTempNumEvents = pSharedInfo->DebugInfo.usNumEvents;
|
||
|
pSharedInfo->DebugInfo.usNumEvents = 0;
|
||
|
for ( ulDebugEventIndex = 0; ulDebugEventIndex < usTempNumEvents; ulDebugEventIndex ++ )
|
||
|
{
|
||
|
/* The HOT channel index for the event is stored at offset 0xF2 (word offset) */
|
||
|
|
||
|
ReadParams.ulReadAddress = pSharedInfo->DebugInfo.ulMatrixBaseAddress + ulReadPointer;
|
||
|
ReadParams.ulReadAddress += 0xF2 * sizeof(UINT16);
|
||
|
ReadParams.pusReadData = &usReadData;
|
||
|
|
||
|
mOCT6100_DRIVER_READ_API( ReadParams, ulResult );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
|
||
|
/* Check if the current debug index is the same as the one found in the event. */
|
||
|
if ( usReadData != pSharedInfo->DebugInfo.usCurrentDebugChanIndex )
|
||
|
pSharedInfo->DebugInfo.usNumEvents = 0; /* As soon as we hit another channel, we reset the number of valid events. */
|
||
|
else
|
||
|
pSharedInfo->DebugInfo.usNumEvents++;
|
||
|
|
||
|
/* Increment read pointer to get next event. */
|
||
|
ulReadPointer = ( ulReadPointer + pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ) % ( ( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize );
|
||
|
}
|
||
|
|
||
|
/* In heavy mode, the AF log pointer is retrieved. */
|
||
|
if ( ( pSharedInfo->DebugInfo.usNumEvents >= 2 )
|
||
|
&& ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S )
|
||
|
|| ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) ) )
|
||
|
{
|
||
|
/* The latest AF log write pointer is at the latest matrix event. */
|
||
|
ReadParams.ulReadAddress = pSharedInfo->DebugInfo.ulMatrixBaseAddress + ( ( pSharedInfo->DebugInfo.usChipDebugEventWritePtr & pSharedInfo->DebugInfo.usMatrixCBMask ) * 1024 );
|
||
|
|
||
|
/* To get the AF log write pointer, which is at offset pSharedInfo->ImageInfo.ulAfWritePtrByteOffset. */
|
||
|
ReadParams.ulReadAddress += pSharedInfo->DebugInfo.ulAfWritePtrByteOffset;
|
||
|
mOCT6100_DRIVER_READ_API( ReadParams, ulResult );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
|
||
|
pSharedInfo->DebugInfo.usAfLogWritePtr = usReadData;
|
||
|
|
||
|
/* The AF event read pointer is the AF write pointer +4096 */
|
||
|
/* This will make sure we do not get mixed up and fetch events that have */
|
||
|
/* just been written, but we think are old. */
|
||
|
|
||
|
/* To get the exact AF log pointer, the API would have to wait 512 milliseconds to make */
|
||
|
/* sure logging had stopped. This is not required since missing a few last events is not */
|
||
|
/* important at this point (the user knows that valid data has already been recorded). */
|
||
|
pSharedInfo->DebugInfo.usLastAfLogReadPtr = (UINT16)( ( pSharedInfo->DebugInfo.usAfLogWritePtr + 4096 ) & 0xFFFF );
|
||
|
|
||
|
/* Note that if the chip has just been booted, some of the AF events might not be initialized. */
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pSharedInfo->DebugInfo.usLastAfLogReadPtr = 0;
|
||
|
pSharedInfo->DebugInfo.usAfLogWritePtr = 0;
|
||
|
}
|
||
|
|
||
|
/* To be aligned correctly for the bursts. */
|
||
|
while ( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ) ) != 0 )
|
||
|
pSharedInfo->DebugInfo.usLastAfLogReadPtr++;
|
||
|
|
||
|
/* Remember the data mode for later checks. Also, the user cannot change this "mode". */
|
||
|
pSharedInfo->DebugInfo.ulCurrentGetDataMode = f_pGetData->ulGetDataMode;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* Check that the user did not change the current data mode. */
|
||
|
if ( pSharedInfo->DebugInfo.ulCurrentGetDataMode != f_pGetData->ulGetDataMode )
|
||
|
return cOCT6100_ERR_DEBUG_GET_DATA_MODE_CANNOT_CHANGE;
|
||
|
}
|
||
|
|
||
|
/* Check if this is the first pass here. */
|
||
|
if ( pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes == cOCT6100_INVALID_VALUE )
|
||
|
{
|
||
|
/* Calculate how many bytes of data will be returned with respect to the selected data content. */
|
||
|
|
||
|
/* Check what content type the user requested. */
|
||
|
if ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE )
|
||
|
{
|
||
|
/* Remember first AF Event Read Pointer. */
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr ) & 0xFF );
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr >> 8 ) & 0xFF );
|
||
|
|
||
|
/* Remember the AF Event Write Pointer. */
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usAfLogWritePtr ) & 0xFF );
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usAfLogWritePtr >> 8 ) & 0xFF );
|
||
|
|
||
|
/* Remember law and hot channel */
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( pChanEntry->TdmConfig.bySinPcmLaw | ( ( pSharedInfo->DebugInfo.usCurrentDebugChanIndex >> 2 ) & 0xFE ) );
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( pChanEntry->TdmConfig.bySoutPcmLaw );
|
||
|
|
||
|
/* Insert light or heavy mode in array. */
|
||
|
if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S_LITE )
|
||
|
|| ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S_LITE ) )
|
||
|
{
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex - 1 ] |= 0x80;
|
||
|
}
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( pChanEntry->TdmConfig.byRinPcmLaw | ( ( pSharedInfo->DebugInfo.usCurrentDebugChanIndex & 0x1F ) << 3 ) );
|
||
|
|
||
|
/* Remember usNumEvents */
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usNumEvents ) & 0xFF );
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->DebugInfo.usNumEvents >> 8 ) & 0xFF );
|
||
|
}
|
||
|
|
||
|
/* Last indexes set to '0'! */
|
||
|
pSharedInfo->DebugInfo.usLastDebugEventIndex = 0;
|
||
|
pSharedInfo->DebugInfo.ulLastPcmSampleIndex = 0;
|
||
|
|
||
|
/* No tone event has been retrieved. */
|
||
|
pSharedInfo->DebugInfo.usLastToneEventIndex = 0;
|
||
|
|
||
|
/* The version strings have not yet been copied. */
|
||
|
pSharedInfo->DebugInfo.fImageVersionCopied = FALSE;
|
||
|
pSharedInfo->DebugInfo.fApiVersionCopied = FALSE;
|
||
|
|
||
|
/* Estimate the total size of the buffer that will be returned. */
|
||
|
f_pGetData->ulTotalNumBytes = ulUserBufWriteIndex;
|
||
|
|
||
|
/* If the full content is requested, add all the debug data. */
|
||
|
if ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE )
|
||
|
{
|
||
|
/* Add the matrix events. */
|
||
|
if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S )
|
||
|
|| ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) )
|
||
|
{
|
||
|
/* Heavy mode! Grab everything! */
|
||
|
f_pGetData->ulTotalNumBytes += pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* Lite mode! Only the most important stuff. */
|
||
|
f_pGetData->ulTotalNumBytes += pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize;
|
||
|
}
|
||
|
|
||
|
/* Add the PCM samples. */
|
||
|
f_pGetData->ulTotalNumBytes += pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize * 3;
|
||
|
|
||
|
/* If requested, add the AF log events. */
|
||
|
if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S )
|
||
|
|| ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) )
|
||
|
{
|
||
|
f_pGetData->ulTotalNumBytes += (UINT32)( ( pSharedInfo->DebugInfo.usAfLogWritePtr - pSharedInfo->DebugInfo.usLastAfLogReadPtr ) & 0xFFFF ) * 16;
|
||
|
}
|
||
|
|
||
|
/* Add the tone events strings. */
|
||
|
f_pGetData->ulTotalNumBytes += cOCT6100_TLV_MAX_TONE_NAME_SIZE * pSharedInfo->ImageInfo.byNumToneDetectors;
|
||
|
|
||
|
/* Add the image version string. */
|
||
|
f_pGetData->ulTotalNumBytes += 512;
|
||
|
|
||
|
/* Add the API version string. */
|
||
|
f_pGetData->ulTotalNumBytes += sizeof( cOCT6100_API_VERSION );
|
||
|
}
|
||
|
else /* if ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) */
|
||
|
{
|
||
|
/* Add one PCM stream. */
|
||
|
f_pGetData->ulTotalNumBytes += pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize;
|
||
|
}
|
||
|
|
||
|
/* Save this in the instance for further calls. */
|
||
|
pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes = f_pGetData->ulTotalNumBytes;
|
||
|
|
||
|
/* Calculate remaining bytes. All the bytes for now! */
|
||
|
f_pGetData->ulRemainingNumBytes = f_pGetData->ulTotalNumBytes;
|
||
|
|
||
|
/* Save this in the instance for the next calls. */
|
||
|
pSharedInfo->DebugInfo.ulDebugDataRemainingNumBytes = f_pGetData->ulRemainingNumBytes;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
f_pGetData->ulTotalNumBytes = pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes;
|
||
|
}
|
||
|
|
||
|
/* Calculate the event read pointer. */
|
||
|
ulReadPointer = ( ( pSharedInfo->DebugInfo.usChipDebugEventWritePtr - pSharedInfo->DebugInfo.usNumEvents ) & pSharedInfo->DebugInfo.usMatrixCBMask ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize;
|
||
|
|
||
|
ulReadPointer += pSharedInfo->DebugInfo.ulDebugChanStatsByteSize * pSharedInfo->DebugInfo.usLastDebugEventIndex;
|
||
|
ulReadPointer %= ( ( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize );
|
||
|
|
||
|
if ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE )
|
||
|
{
|
||
|
/* Copy the debug events in the user buffer. */
|
||
|
for( ulDebugEventIndex = pSharedInfo->DebugInfo.usLastDebugEventIndex; ulDebugEventIndex < pSharedInfo->DebugInfo.usNumEvents; ulDebugEventIndex ++ )
|
||
|
{
|
||
|
ReadBurstParams.ulReadAddress = pSharedInfo->DebugInfo.ulMatrixBaseAddress + ulReadPointer;
|
||
|
|
||
|
/* Check if we are in light or heavy mode. The burst size is not the same. */
|
||
|
if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S )
|
||
|
|| ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) )
|
||
|
{
|
||
|
if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) >= pSharedInfo->DebugInfo.ulDebugChanStatsByteSize )
|
||
|
ulNumReads = pSharedInfo->DebugInfo.ulDebugChanStatsByteSize / 2;
|
||
|
else
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) >= pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize )
|
||
|
ulNumReads = pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize / 2;
|
||
|
else
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
ulTempIndex = 0;
|
||
|
while ( ulNumReads != 0 )
|
||
|
{
|
||
|
if ( ulNumReads >= pSharedInfo->ChipConfig.usMaxRwAccesses )
|
||
|
ReadBurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses;
|
||
|
else
|
||
|
ReadBurstParams.ulReadLength = ulNumReads;
|
||
|
|
||
|
/* Set pointer where to write data. */
|
||
|
ReadBurstParams.pusReadData = pSharedInfo->MiscVars.ausSuperArray;
|
||
|
|
||
|
mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
|
||
|
/* Copy data byte per byte to avoid endianess problems. */
|
||
|
for ( ulCopyIndex = 0; ulCopyIndex < ReadBurstParams.ulReadLength; ulCopyIndex ++ )
|
||
|
{
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex + ulTempIndex + ( 2 * ulCopyIndex ) ] = (UINT8)( ReadBurstParams.pusReadData[ ulCopyIndex ] & 0xFF );
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex + ulTempIndex + ( 2 * ulCopyIndex ) + 1 ] = (UINT8)( ( ReadBurstParams.pusReadData[ ulCopyIndex ] >> 8 ) & 0xFF );
|
||
|
}
|
||
|
|
||
|
/* Update indexes, temp variables, addresses. */
|
||
|
ulNumReads -= ReadBurstParams.ulReadLength;
|
||
|
ulTempIndex += ReadBurstParams.ulReadLength * 2;
|
||
|
ReadBurstParams.ulReadAddress += ReadBurstParams.ulReadLength * 2;
|
||
|
}
|
||
|
|
||
|
/* Store register 0x202 in the event structure. */
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex + 255 ] = (UINT8)( pSharedInfo->IntrptManage.usRegister202h & 0xFF );
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex + 256 ] = (UINT8)( ( pSharedInfo->IntrptManage.usRegister202h >> 8 ) & 0xFF );
|
||
|
|
||
|
/* Increment index. */
|
||
|
if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S )
|
||
|
|| ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) )
|
||
|
{
|
||
|
ulUserBufWriteIndex += pSharedInfo->DebugInfo.ulDebugChanStatsByteSize;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ulUserBufWriteIndex += pSharedInfo->DebugInfo.ulDebugChanLiteStatsByteSize;
|
||
|
}
|
||
|
|
||
|
/* Increment read pointer to get next event. */
|
||
|
ulReadPointer = ( ulReadPointer + pSharedInfo->DebugInfo.ulDebugChanStatsByteSize ) % ( ( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) * pSharedInfo->DebugInfo.ulDebugChanStatsByteSize );
|
||
|
|
||
|
/* Save in the instance that one of the events was dumped. */
|
||
|
pSharedInfo->DebugInfo.usLastDebugEventIndex ++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Check if all debug events have been transfered. */
|
||
|
if ( ( ulDebugEventIndex == pSharedInfo->DebugInfo.usNumEvents )
|
||
|
|| ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) )
|
||
|
{
|
||
|
/* Fetch all streams per event. */
|
||
|
for ( ulPcmSampleIndex = pSharedInfo->DebugInfo.ulLastPcmSampleIndex; ulPcmSampleIndex < ( (UINT32)pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ); ulPcmSampleIndex ++ )
|
||
|
{
|
||
|
/* Check if enough room for this sample. */
|
||
|
if ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE )
|
||
|
{
|
||
|
if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) < 1 )
|
||
|
break;
|
||
|
}
|
||
|
else /* if ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) */
|
||
|
{
|
||
|
if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) < 3 )
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* Check if must retrieve data from external memory. */
|
||
|
if ( ( ulPcmSampleIndex % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE * 2 ) ) == 0x0 )
|
||
|
{
|
||
|
ulReadPointer = ( ( ( pSharedInfo->DebugInfo.usChipDebugEventWritePtr - pSharedInfo->DebugInfo.usNumEvents ) * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ) & ( pSharedInfo->DebugInfo.usMatrixCBMask * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ) );
|
||
|
ulReadPointer += ( ulPcmSampleIndex / pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ) * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize;
|
||
|
ulReadPointer &= ( pSharedInfo->DebugInfo.usMatrixCBMask * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize );
|
||
|
ulReadPointer += ulPcmSampleIndex % pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize;
|
||
|
|
||
|
/* Retrieve more data from external memory. */
|
||
|
switch ( f_pGetData->ulGetDataContent )
|
||
|
{
|
||
|
case cOCT6100_DEBUG_GET_DATA_CONTENT_RIN_PCM:
|
||
|
ulStreamIndexMin = 0;
|
||
|
ulStreamIndexMax = 1;
|
||
|
break;
|
||
|
case cOCT6100_DEBUG_GET_DATA_CONTENT_SIN_PCM:
|
||
|
ulStreamIndexMin = 1;
|
||
|
ulStreamIndexMax = 2;
|
||
|
break;
|
||
|
case cOCT6100_DEBUG_GET_DATA_CONTENT_SOUT_PCM:
|
||
|
ulStreamIndexMin = 2;
|
||
|
ulStreamIndexMax = 3;
|
||
|
break;
|
||
|
case cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE:
|
||
|
default:
|
||
|
ulStreamIndexMin = 0;
|
||
|
ulStreamIndexMax = 3;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
for ( ulStreamIndex = ulStreamIndexMin; ulStreamIndex < ulStreamIndexMax; ulStreamIndex ++ )
|
||
|
{
|
||
|
ReadBurstParams.ulReadAddress = pSharedInfo->MemoryMap.ulChanMainMemBase;
|
||
|
/* To get right channel information. */
|
||
|
ReadBurstParams.ulReadAddress += ( ( pSharedInfo->DebugInfo.usRecordMemIndex + 2 ) * pSharedInfo->MemoryMap.ulChanMainMemSize ) + pSharedInfo->DebugInfo.ulAfEventCbByteSize;
|
||
|
/* To get correct stream. */
|
||
|
ReadBurstParams.ulReadAddress += ( ( pSharedInfo->DebugInfo.usMatrixCBMask + 1 ) * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize * ulStreamIndex );
|
||
|
/* PCM sample pointer in that stream. */
|
||
|
ReadBurstParams.ulReadAddress += ulReadPointer;
|
||
|
|
||
|
/* As much as we can for the burst. */
|
||
|
ulTempIndex = 0;
|
||
|
ulNumReads = cOCT6100_INTERNAL_SUPER_ARRAY_SIZE;
|
||
|
while ( ulNumReads != 0 )
|
||
|
{
|
||
|
if ( ulNumReads >= pSharedInfo->ChipConfig.usMaxRwAccesses )
|
||
|
ReadBurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses;
|
||
|
else
|
||
|
ReadBurstParams.ulReadLength = ulNumReads;
|
||
|
|
||
|
/* Set pointer where to write data. */
|
||
|
if ( ulStreamIndex == 0 )
|
||
|
ReadBurstParams.pusReadData = &pSharedInfo->MiscVars.ausSuperArray[ ulTempIndex ];
|
||
|
else if ( ulStreamIndex == 1 )
|
||
|
ReadBurstParams.pusReadData = &pSharedInfo->MiscVars.ausSuperArray1[ ulTempIndex ];
|
||
|
else /* if ( ulStreamIndex == 2 ) */
|
||
|
ReadBurstParams.pusReadData = &pSharedInfo->MiscVars.ausSuperArray2[ ulTempIndex ];
|
||
|
|
||
|
mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
|
||
|
/* Update indexes, temp variables, addresses. */
|
||
|
ulNumReads -= ReadBurstParams.ulReadLength;
|
||
|
ulTempIndex += ReadBurstParams.ulReadLength;
|
||
|
ReadBurstParams.ulReadAddress += ReadBurstParams.ulReadLength * 2;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* We now have the stream data for all streams for 1 event. */
|
||
|
/* Return what we can to the user. */
|
||
|
if ( ( ulPcmSampleIndex % 2 ) == 0 )
|
||
|
{
|
||
|
if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE )
|
||
|
|| ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_RIN_PCM ) )
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 8 ) & 0xFF );
|
||
|
|
||
|
if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE )
|
||
|
|| ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_SIN_PCM ) )
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray1[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 8 ) & 0xFF );
|
||
|
|
||
|
if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE )
|
||
|
|| ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_SOUT_PCM ) )
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray2[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 8 ) & 0xFF );
|
||
|
}
|
||
|
else /* if ( ulPcmSampleIndex % 2 == 1 ) */
|
||
|
{
|
||
|
if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE )
|
||
|
|| ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_RIN_PCM ) )
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 0 ) & 0xFF );
|
||
|
|
||
|
if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE )
|
||
|
|| ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_SIN_PCM ) )
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray1[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 0 ) & 0xFF );
|
||
|
|
||
|
if ( ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE )
|
||
|
|| ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_SOUT_PCM ) )
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray2[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 0 ) & 0xFF );
|
||
|
}
|
||
|
|
||
|
pSharedInfo->DebugInfo.ulLastPcmSampleIndex++;
|
||
|
}
|
||
|
|
||
|
/* Check if we are done dumping the PCM samples! */
|
||
|
if ( pSharedInfo->DebugInfo.ulLastPcmSampleIndex == ( (UINT32)pSharedInfo->DebugInfo.usNumEvents * pSharedInfo->DebugInfo.ulRecordedPcmEventByteSize ) )
|
||
|
{
|
||
|
if ( f_pGetData->ulGetDataContent == cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE )
|
||
|
{
|
||
|
|
||
|
/* Go for the AF events. The AF events are only copied in heavy mode. */
|
||
|
if ( ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_16S )
|
||
|
|| ( f_pGetData->ulGetDataMode == cOCT6100_DEBUG_GET_DATA_MODE_120S ) )
|
||
|
{
|
||
|
while ( pSharedInfo->DebugInfo.usLastAfLogReadPtr != pSharedInfo->DebugInfo.usAfLogWritePtr )
|
||
|
{
|
||
|
/* Check if enough room for an event. */
|
||
|
if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) < 16 )
|
||
|
break;
|
||
|
|
||
|
/* Check if must fill our buffer. */
|
||
|
if ( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ) ) == 0x0 )
|
||
|
{
|
||
|
ulNumAfEvents = ( pSharedInfo->DebugInfo.usAfLogWritePtr - pSharedInfo->DebugInfo.usLastAfLogReadPtr ) & 0xFFFF;
|
||
|
|
||
|
/* Check for the size of the available buffer. */
|
||
|
if ( ulNumAfEvents > ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ) )
|
||
|
ulNumAfEvents = ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 );
|
||
|
|
||
|
/* Start at channel main base address. */
|
||
|
ReadBurstParams.ulReadAddress = pSharedInfo->MemoryMap.ulChanMainMemBase;
|
||
|
/* To get right channel information. */
|
||
|
ReadBurstParams.ulReadAddress += ( ( pSharedInfo->DebugInfo.usRecordMemIndex + 2 ) * pSharedInfo->MemoryMap.ulChanMainMemSize );
|
||
|
/* To get the right AF log. */
|
||
|
ReadBurstParams.ulReadAddress += ( pSharedInfo->DebugInfo.usLastAfLogReadPtr * 16 );
|
||
|
|
||
|
ulTempIndex = 0;
|
||
|
ulNumReads = ulNumAfEvents * 8;
|
||
|
|
||
|
while ( ulNumReads != 0 )
|
||
|
{
|
||
|
if ( ulNumReads >= pSharedInfo->ChipConfig.usMaxRwAccesses )
|
||
|
ReadBurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses;
|
||
|
else
|
||
|
ReadBurstParams.ulReadLength = ulNumReads;
|
||
|
|
||
|
/* Set pointer where to write data. */
|
||
|
ReadBurstParams.pusReadData = &pSharedInfo->MiscVars.ausSuperArray[ ulTempIndex ];
|
||
|
|
||
|
mOCT6100_DRIVER_READ_BURST_API( ReadBurstParams, ulResult );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
|
||
|
/* Update indexes, temp variables, addresses. */
|
||
|
ulNumReads -= ReadBurstParams.ulReadLength;
|
||
|
ulTempIndex += ReadBurstParams.ulReadLength;
|
||
|
ReadBurstParams.ulReadAddress += ReadBurstParams.ulReadLength * 2;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Copy data byte per byte to avoid endianess problems. */
|
||
|
for ( ulCopyIndex = 0; ulCopyIndex < 8; ulCopyIndex ++ )
|
||
|
{
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex + ( 2 * ulCopyIndex ) ] = (UINT8)( pSharedInfo->MiscVars.ausSuperArray[ ( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ) ) * 8 ) + ulCopyIndex ] & 0xFF );
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex + ( 2 * ulCopyIndex ) + 1 ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray[ ( ( pSharedInfo->DebugInfo.usLastAfLogReadPtr % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE / 8 ) ) * 8 ) + ulCopyIndex ] >> 8 ) & 0xFF );
|
||
|
}
|
||
|
|
||
|
ulUserBufWriteIndex += 16;
|
||
|
|
||
|
/* Increment AF log read ptr. */
|
||
|
pSharedInfo->DebugInfo.usLastAfLogReadPtr = (UINT16)(( pSharedInfo->DebugInfo.usLastAfLogReadPtr + 1 ) & 0xFFFF );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Check if we are done with the AF events. */
|
||
|
if ( pSharedInfo->DebugInfo.usLastAfLogReadPtr == pSharedInfo->DebugInfo.usAfLogWritePtr )
|
||
|
{
|
||
|
/* Insert the tone event information. */
|
||
|
for ( ulToneEventIndex = pSharedInfo->DebugInfo.usLastToneEventIndex; ulToneEventIndex < pSharedInfo->ImageInfo.byNumToneDetectors; ulToneEventIndex++ )
|
||
|
{
|
||
|
if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) < cOCT6100_TLV_MAX_TONE_NAME_SIZE )
|
||
|
break;
|
||
|
|
||
|
Oct6100UserMemCopy( &f_pGetData->pbyData[ ulUserBufWriteIndex ], pSharedInfo->ImageInfo.aToneInfo[ ulToneEventIndex ].aszToneName, cOCT6100_TLV_MAX_TONE_NAME_SIZE );
|
||
|
|
||
|
ulUserBufWriteIndex += cOCT6100_TLV_MAX_TONE_NAME_SIZE;
|
||
|
|
||
|
pSharedInfo->DebugInfo.usLastToneEventIndex++;
|
||
|
}
|
||
|
|
||
|
/* If all the tone information has been copied. */
|
||
|
if ( ulToneEventIndex == pSharedInfo->ImageInfo.byNumToneDetectors )
|
||
|
{
|
||
|
/* Copy the image version. */
|
||
|
if ( pSharedInfo->DebugInfo.fImageVersionCopied == FALSE )
|
||
|
{
|
||
|
if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) >= 512 )
|
||
|
{
|
||
|
Oct6100UserMemCopy( &f_pGetData->pbyData[ ulUserBufWriteIndex ], pSharedInfo->ImageInfo.szVersionNumber, 512 );
|
||
|
|
||
|
/* Get PLL jitter count from external memory. */
|
||
|
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 );
|
||
|
|
||
|
/* Create the mask to retrieve the appropriate value. */
|
||
|
mOCT6100_CREATE_FEATURE_MASK( ulFeatureFieldLength, ulFeatureBitOffset, &ulMask );
|
||
|
|
||
|
/* Mask data. */
|
||
|
ulTempData &= ulMask;
|
||
|
/* Move to right position. */
|
||
|
ulTempData = ulTempData >> ulFeatureBitOffset;
|
||
|
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex + 510 ] = (UINT8)( ( ulTempData >> 8 ) & 0xFF );
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex + 511 ] = (UINT8)( ( ulTempData >> 0 ) & 0xFF );
|
||
|
}
|
||
|
|
||
|
/* Add "ISR is not called" bit. */
|
||
|
if ( pSharedInfo->IntrptManage.fIsrCalled == FALSE )
|
||
|
{
|
||
|
f_pGetData->pbyData[ ulUserBufWriteIndex + 510 ] |= 0x80;
|
||
|
}
|
||
|
|
||
|
ulUserBufWriteIndex += 512;
|
||
|
|
||
|
/* The version has been copied. */
|
||
|
pSharedInfo->DebugInfo.fImageVersionCopied = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* If the image version has been copied, proceed with the API version. */
|
||
|
if ( pSharedInfo->DebugInfo.fImageVersionCopied == TRUE )
|
||
|
{
|
||
|
if ( pSharedInfo->DebugInfo.fApiVersionCopied == FALSE )
|
||
|
{
|
||
|
if ( ( f_pGetData->ulMaxBytes - ulUserBufWriteIndex ) >= sizeof(cOCT6100_API_VERSION) )
|
||
|
{
|
||
|
Oct6100UserMemCopy( &f_pGetData->pbyData[ ulUserBufWriteIndex ], cOCT6100_API_VERSION, sizeof(cOCT6100_API_VERSION) );
|
||
|
ulUserBufWriteIndex += sizeof(cOCT6100_API_VERSION);
|
||
|
|
||
|
/* The API version has been copied. */
|
||
|
pSharedInfo->DebugInfo.fApiVersionCopied = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Check if we are done! */
|
||
|
if ( pSharedInfo->DebugInfo.fApiVersionCopied == TRUE )
|
||
|
{
|
||
|
/* Done dumping. */
|
||
|
|
||
|
/* Reset data being dumpped flag. */
|
||
|
pSharedInfo->DebugInfo.fDebugDataBeingDumped = FALSE;
|
||
|
|
||
|
/* Reset data recording in the chip. */
|
||
|
WriteBurstParams.ulWriteAddress = pSharedInfo->DebugInfo.ulHotChannelSelectBaseAddress;
|
||
|
WriteBurstParams.ulWriteLength = 2;
|
||
|
WriteBurstParams.pusWriteData = pSharedInfo->DebugInfo.ausHotChannelData;
|
||
|
|
||
|
mOCT6100_DRIVER_WRITE_BURST_API( WriteBurstParams, ulResult );
|
||
|
if ( ulResult != cOCT6100_ERR_OK )
|
||
|
return ulResult;
|
||
|
|
||
|
fResetRemainingDataFlag = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else /* if ( f_pGetData->ulGetDataContent != cOCT6100_DEBUG_GET_DATA_CONTENT_COMPLETE ) */
|
||
|
{
|
||
|
fResetRemainingDataFlag = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Return number of valid bytes in buffer to user. */
|
||
|
f_pGetData->ulValidNumBytes = ulUserBufWriteIndex;
|
||
|
|
||
|
/* Update remaining bytes. */
|
||
|
pSharedInfo->DebugInfo.ulDebugDataRemainingNumBytes -= ulUserBufWriteIndex;
|
||
|
|
||
|
/* Return remaining bytes. */
|
||
|
f_pGetData->ulRemainingNumBytes = pSharedInfo->DebugInfo.ulDebugDataRemainingNumBytes;
|
||
|
|
||
|
/* Return total number of bytes. */
|
||
|
f_pGetData->ulTotalNumBytes = pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes;
|
||
|
|
||
|
/* Check if we are done dump the requested content. */
|
||
|
if ( fResetRemainingDataFlag == TRUE )
|
||
|
pSharedInfo->DebugInfo.ulDebugDataTotalNumBytes = cOCT6100_INVALID_VALUE;
|
||
|
|
||
|
return cOCT6100_ERR_OK;
|
||
|
}
|
||
|
#endif
|