summaryrefslogtreecommitdiff
path: root/software/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'software/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.c')
-rw-r--r--software/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.c1100
1 files changed, 1100 insertions, 0 deletions
diff --git a/software/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.c b/software/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.c
new file mode 100644
index 0000000..3573cc0
--- /dev/null
+++ b/software/octdeviceapi/oct6100api/oct6100_api/oct6100_debug.c
@@ -0,0 +1,1100 @@
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
+
+File: oct6100_debug.c
+
+ Copyright (c) 2001-2005 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-PR38 $
+
+$Octasic_Revision: 58 $
+
+\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+
+
+/***************************** 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.
+
+\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+UINT32 Oct6100DebugSelectChannelDef(
+ tPOCT6100_DEBUG_SELECT_CHANNEL f_pSelectDebugChan )
+{
+ f_pSelectDebugChan->ulChannelHndl = cOCT6100_INVALID_VALUE;
+
+ return cOCT6100_ERR_OK;
+}
+
+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;
+}
+
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
+
+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.
+
+\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+UINT32 Oct6100DebugGetDataDef(
+ tPOCT6100_DEBUG_GET_DATA f_pGetData )
+{
+ f_pGetData->ulGetDataMode = cOCT6100_DEBUG_GET_DATA_MODE_120S_LITE;
+ 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;
+}
+
+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;
+}
+
+
+/**************************** 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.
+
+\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+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;
+ UINT16 usChanIndex = 0;
+ UINT32 ulEntryOpenCnt;
+
+ tOCT6100_WRITE_BURST_PARAMS BurstParams;
+ 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 )
+ {
+ ulResult = Oct6100ApiReleaseTsiMemEntry( f_pApiInstance, pTempChanEntry->usExtraSinTsiMemIndex );
+ if ( ulResult != cOCT6100_ERR_OK )
+ return ulResult;
+
+ 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->usExtraSinTsiDependencyCnt--;
+ pTempChanEntry->usExtraSinTsiMemIndex = cOCT6100_INVALID_INDEX;
+ }
+ }
+
+ /* 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 )
+ {
+ if ( pChanEntry->usExtraSinTsiMemIndex == cOCT6100_INVALID_INDEX )
+ {
+ ulResult = Oct6100ApiReserveTsiMemEntry( f_pApiInstance, &pChanEntry->usExtraSinTsiMemIndex );
+ if ( ulResult != cOCT6100_ERR_OK )
+ return ulResult;
+
+ if ( pChanEntry->usSinTsstIndex != cOCT6100_INVALID_INDEX )
+ {
+ ulResult = Oct6100ApiWriteInputTsstControlMemory( f_pApiInstance,
+ pChanEntry->usSinTsstIndex,
+ pChanEntry->usExtraSinTsiMemIndex,
+ pChanEntry->TdmConfig.bySinPcmLaw );
+ 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 = 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;
+ }
+
+ if ( pSharedInfo->ChipConfig.fEnableChannelRecording == TRUE )
+ {
+ /* 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;
+
+ if ( ( f_pSelectDebugChan->ulChannelHndl != cOCT6100_INVALID_HANDLE )
+ && ( pChanEntry != NULL ) )
+ {
+ /* 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;
+ }
+ else
+ {
+ /* Hard-code this to u-Law. */
+ TempChanOpen.TdmConfig.ulRinPcmLaw = cOCT6100_PCM_U_LAW;
+ TempChanOpen.TdmConfig.ulSinPcmLaw = cOCT6100_PCM_U_LAW;
+ TempChanOpen.TdmConfig.ulRoutPcmLaw = cOCT6100_PCM_U_LAW;
+ TempChanOpen.TdmConfig.ulSoutPcmLaw = cOCT6100_PCM_U_LAW;
+ }
+
+ 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;
+
+ /* 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;
+}
+
+
+/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
+
+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.
+
+\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
+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;
+
+ UINT32 ulResult;
+ UINT32 ulToneEventIndex;
+ UINT32 ulReadPointer;
+ UINT32 ulUserBufWriteIndex = 0;
+ UINT32 ulTimestamp;
+ UINT32 ulDebugEventIndex;
+ UINT32 ulStreamIndex;
+ UINT32 ulPcmSampleIndex;
+ UINT32 ulNumAfEvents;
+ UINT32 ulNumReads = 0;
+ UINT32 ulTempIndex;
+ UINT32 ulCopyIndex;
+ UINT32 ulFeatureBytesOffset;
+ UINT32 ulFeatureBitOffset;
+ UINT32 ulFeatureFieldLength;
+ UINT32 ulTempData;
+ UINT32 ulMask;
+
+ /* 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 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 )
+ {
+ 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;
+ 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 );
+ }
+
+ /* 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 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;
+
+ /* 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 );
+
+ /* 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 );
+
+ /* 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 )
+ {
+ /* 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->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. */
+ for ( ulStreamIndex = 0; ulStreamIndex < 3; 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 )
+ {
+ f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 8 ) & 0xFF );
+ f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray1[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 8 ) & 0xFF );
+ f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray2[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 8 ) & 0xFF );
+ }
+ else /* if ( ulPcmSampleIndex % 2 == 1 ) */
+ {
+ f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 0 ) & 0xFF );
+ f_pGetData->pbyData[ ulUserBufWriteIndex++ ] = (UINT8)( ( pSharedInfo->MiscVars.ausSuperArray1[ ( ulPcmSampleIndex / 2 ) % ( cOCT6100_INTERNAL_SUPER_ARRAY_SIZE ) ] >> 0 ) & 0xFF );
+ 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 ) )
+ {
+ /* 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;
+ }
+ }
+ }
+ }
+
+ /* 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;
+
+ return cOCT6100_ERR_OK;
+}