1
#ifndef cOCT6100_REMOVE_EVENTS
2
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
6
Copyright (c) 2001-2006 Octasic Inc.
10
This file contains functions used to retrieve tone and playout events.
12
This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is
13
free software; you can redistribute it and/or modify it under the terms of
14
the GNU General Public License as published by the Free Software Foundation;
15
either version 2 of the License, or (at your option) any later version.
17
The OCT6100 GPL API is distributed in the hope that it will be useful, but
18
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22
You should have received a copy of the GNU General Public License
23
along with the OCT6100 GPL API; if not, write to the Free Software
24
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26
$Octasic_Release: OCT612xAPI-01.00-PR43 $
28
$Octasic_Revision: 79 $
30
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
33
/***************************** INCLUDE FILES *******************************/
37
#include "oct6100api/oct6100_defines.h"
38
#include "oct6100api/oct6100_errors.h"
39
#include "oct6100api/oct6100_apiud.h"
41
#include "apilib/octapi_llman.h"
43
#include "oct6100api/oct6100_tlv_inst.h"
44
#include "oct6100api/oct6100_chip_open_inst.h"
45
#include "oct6100api/oct6100_chip_stats_inst.h"
46
#include "oct6100api/oct6100_interrupts_inst.h"
47
#include "oct6100api/oct6100_remote_debug_inst.h"
48
#include "oct6100api/oct6100_debug_inst.h"
49
#include "oct6100api/oct6100_api_inst.h"
50
#include "oct6100api/oct6100_channel_inst.h"
51
#include "oct6100api/oct6100_events_inst.h"
52
#include "oct6100api/oct6100_tone_detection_inst.h"
53
#include "oct6100api/oct6100_playout_buf_inst.h"
55
#include "oct6100api/oct6100_interrupts_pub.h"
56
#include "oct6100api/oct6100_chip_open_pub.h"
57
#include "oct6100api/oct6100_channel_pub.h"
58
#include "oct6100api/oct6100_events_pub.h"
59
#include "oct6100api/oct6100_tone_detection_pub.h"
60
#include "oct6100api/oct6100_playout_buf_pub.h"
62
#include "oct6100_chip_open_priv.h"
63
#include "oct6100_miscellaneous_priv.h"
64
#include "oct6100_channel_priv.h"
65
#include "oct6100_events_priv.h"
66
#include "oct6100_tone_detection_priv.h"
67
#include "oct6100_playout_buf_priv.h"
69
/**************************** PUBLIC FUNCTIONS *****************************/
71
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
73
Function: Oct6100EventGetTone
75
Description: Retreives an array of tone events.
77
-------------------------------------------------------------------------------
78
| Argument | Description
79
-------------------------------------------------------------------------------
80
f_pApiInstance Pointer to API instance. This memory is used to keep
81
the present state of the chip and all its resources.
83
f_pEventGetTone Pointer to structure used to store the Tone events.
85
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
86
#if !SKIP_Oct6100EventGetToneDef
87
UINT32 Oct6100EventGetToneDef(
88
tPOCT6100_EVENT_GET_TONE f_pEventGetTone )
90
f_pEventGetTone->pToneEvent = NULL;
91
f_pEventGetTone->ulMaxToneEvent = 1;
92
f_pEventGetTone->ulNumValidToneEvent = cOCT6100_INVALID_VALUE;
93
f_pEventGetTone->fMoreEvents = FALSE;
94
f_pEventGetTone->fResetBufs = FALSE;
96
return cOCT6100_ERR_OK;
101
#if !SKIP_Oct6100EventGetTone
102
UINT32 Oct6100EventGetTone(
103
tPOCT6100_INSTANCE_API f_pApiInstance,
104
tPOCT6100_EVENT_GET_TONE f_pEventGetTone )
106
tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj;
107
tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj;
108
UINT32 ulSerRes = cOCT6100_ERR_OK;
109
UINT32 ulFncRes = cOCT6100_ERR_OK;
111
/* Set the process context of the serialize structure. */
112
SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext;
113
ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext;
115
/* Seize all list semaphores needed by this function. */
116
SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
117
SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY;
118
ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj );
119
if ( ulSerRes == cOCT6100_ERR_OK )
121
/* Call the serialized function. */
122
ulFncRes = Oct6100EventGetToneSer( f_pApiInstance, f_pEventGetTone );
129
/* Release the seized semaphores. */
130
ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
131
ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj );
133
/* If an error occured then return the error code. */
134
if ( ulSerRes != cOCT6100_ERR_OK )
136
if ( ulFncRes != cOCT6100_ERR_OK )
139
return cOCT6100_ERR_OK;
144
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
146
Function: Oct6100BufferPlayoutGetEvent
148
Description: Retrieves an array of playout stop events.
150
-------------------------------------------------------------------------------
151
| Argument | Description
152
-------------------------------------------------------------------------------
153
f_pApiInstance Pointer to API instance. This memory is used to keep
154
the present state of the chip and all its resources.
156
f_pBufPlayoutGetEvent Pointer to structure used to store the playout events.
158
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
159
#if !SKIP_Oct6100BufferPlayoutGetEventDef
160
UINT32 Oct6100BufferPlayoutGetEventDef(
161
tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent )
163
f_pBufPlayoutGetEvent->pBufferPlayoutEvent = NULL;
164
f_pBufPlayoutGetEvent->ulMaxEvent = 1;
165
f_pBufPlayoutGetEvent->ulNumValidEvent = cOCT6100_INVALID_VALUE;
166
f_pBufPlayoutGetEvent->fMoreEvents = FALSE;
167
f_pBufPlayoutGetEvent->fResetBufs = FALSE;
169
return cOCT6100_ERR_OK;
174
#if !SKIP_Oct6100BufferPlayoutGetEvent
175
UINT32 Oct6100BufferPlayoutGetEvent(
176
tPOCT6100_INSTANCE_API f_pApiInstance,
177
tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent )
179
tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj;
180
tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj;
181
UINT32 ulSerRes = cOCT6100_ERR_OK;
182
UINT32 ulFncRes = cOCT6100_ERR_OK;
184
/* Set the process context of the serialize structure. */
185
SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext;
186
ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext;
188
/* Seize all list semaphores needed by this function. */
189
SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
190
SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY;
191
ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj );
192
if ( ulSerRes == cOCT6100_ERR_OK )
194
/* Call the serialized function. */
195
ulFncRes = Oct6100BufferPlayoutGetEventSer( f_pApiInstance, f_pBufPlayoutGetEvent );
202
/* Release the seized semaphores. */
203
ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
204
ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj );
206
/* If an error occured then return the error code. */
207
if ( ulSerRes != cOCT6100_ERR_OK )
209
if ( ulFncRes != cOCT6100_ERR_OK )
212
return cOCT6100_ERR_OK;
217
/**************************** PRIVATE FUNCTIONS ****************************/
219
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
221
Function: Oct6100ApiGetEventsSwSizes
223
Description: Gets the sizes of all portions of the API instance pertinent
224
to the management of the tone events and playout events
227
-------------------------------------------------------------------------------
228
| Argument | Description
229
-------------------------------------------------------------------------------
230
f_pOpenChip Pointer to chip configuration struct.
231
f_pInstSizes Pointer to struct containing instance sizes.
233
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
234
#if !SKIP_Oct6100ApiGetEventsSwSizes
235
UINT32 Oct6100ApiGetEventsSwSizes(
236
IN tPOCT6100_CHIP_OPEN f_pOpenChip,
237
OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes )
243
/* Memory needed by soft tone event buffers. */
245
/* Add 1 to the circular buffer such that all user requested events can fit in the circular queue. */
246
f_pInstSizes->ulSoftToneEventsBuffer = ( f_pOpenChip->ulSoftToneEventsBufSize + 1 ) * sizeof( tOCT6100_API_TONE_EVENT );
248
/* Round off the sizes of the soft buffers above. */
249
mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulSoftToneEventsBuffer, ulTempVar )
255
/* Memory needed by soft playout stop event buffers. */
256
if ( f_pOpenChip->ulSoftBufferPlayoutEventsBufSize != cOCT6100_INVALID_VALUE )
258
f_pInstSizes->ulSoftBufPlayoutEventsBuffer = ( f_pOpenChip->ulSoftBufferPlayoutEventsBufSize + 1 ) * sizeof( tOCT6100_API_BUFFER_PLAYOUT_EVENT );
260
/* Round off the sizes of the soft buffers above. */
261
mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulSoftBufPlayoutEventsBuffer, ulTempVar )
263
else /* if ( f_pInstSizes->ulSoftBufferPlayoutEventsBufSize == cOCT6100_INVALID_VALUE ) */
265
f_pInstSizes->ulSoftBufPlayoutEventsBuffer = 0;
269
return cOCT6100_ERR_OK;
274
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
276
Function: Oct6100EventGetToneSer
278
Description: Retreives an array of tone event from the software event buffer.
280
-------------------------------------------------------------------------------
281
| Argument | Description
282
-------------------------------------------------------------------------------
283
f_pApiInstance Pointer to API instance. This memory is used to keep
284
the present state of the chip and all its resources.
286
f_pEventGetTone Pointer to structure which will contain the retreived
289
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
290
#if !SKIP_Oct6100EventGetToneSer
291
UINT32 Oct6100EventGetToneSer(
292
IN OUT tPOCT6100_INSTANCE_API f_pApiInstance,
293
IN OUT tPOCT6100_EVENT_GET_TONE f_pEventGetTone )
295
tPOCT6100_SHARED_INFO pSharedInfo;
296
tPOCT6100_API_TONE_EVENT pSoftEvent;
297
UINT32 ulSoftReadPnt;
298
UINT32 ulSoftWritePnt;
299
UINT32 ulSoftBufSize;
300
UINT32 ulNumEventsReturned;
303
/* Get local pointer(s). */
304
pSharedInfo = f_pApiInstance->pSharedInfo;
306
/* Check the parameters given by the user. */
307
if ( f_pEventGetTone->fResetBufs != TRUE &&
308
f_pEventGetTone->fResetBufs != FALSE )
309
return cOCT6100_ERR_EVENTS_GET_TONE_RESET_BUFS;
311
/* Check max tones. */
312
if ( f_pEventGetTone->ulMaxToneEvent > pSharedInfo->ChipConfig.ulSoftToneEventsBufSize )
313
return cOCT6100_ERR_EVENTS_MAX_TONES;
315
if ( f_pEventGetTone->fResetBufs == FALSE )
317
/* Check if the events need to be fetched from the chip buffer. */
318
ulSoftReadPnt = pSharedInfo->SoftBufs.ulToneEventBufferReadPtr;
319
ulSoftWritePnt = pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
321
if ( ulSoftReadPnt == ulSoftWritePnt )
323
ulResult = Oct6100ApiTransferToneEvents( f_pApiInstance, f_pEventGetTone->fResetBufs );
324
if ( ulResult != cOCT6100_ERR_OK )
328
/* If there are no events in the soft buffer then there are none in the chip */
329
/* either, so return the empty case. Else, return the events in the buffer. */
330
ulSoftReadPnt = pSharedInfo->SoftBufs.ulToneEventBufferReadPtr;
331
ulSoftWritePnt = pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
332
ulSoftBufSize = pSharedInfo->SoftBufs.ulToneEventBufferSize;
334
if ( ulSoftReadPnt != ulSoftWritePnt )
336
ulNumEventsReturned = 0;
338
while( (ulSoftReadPnt != ulSoftWritePnt) && ( ulNumEventsReturned != f_pEventGetTone->ulMaxToneEvent) )
340
/* Get a pointer to the first event in the buffer. */
341
mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
342
pSoftEvent += ulSoftReadPnt;
344
f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulChannelHndl = pSoftEvent->ulChannelHandle;
345
f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulUserChanId = pSoftEvent->ulUserChanId;
346
f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulTimestamp = pSoftEvent->ulTimestamp;
347
f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulEventType = pSoftEvent->ulEventType;
348
f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulToneDetected = pSoftEvent->ulToneDetected;
349
f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulExtToneDetectionPort = pSoftEvent->ulExtToneDetectionPort;
351
/* Update the pointers of the soft buffer. */
353
if ( ulSoftReadPnt == ulSoftBufSize )
356
ulNumEventsReturned++;
359
pSharedInfo->SoftBufs.ulToneEventBufferReadPtr = ulSoftReadPnt;
361
/* Detemine if there are more events pending in the soft buffer. */
362
if ( ulSoftReadPnt != ulSoftWritePnt )
363
f_pEventGetTone->fMoreEvents = TRUE;
364
else /* ( ulSoftReadPnt == ulSoftWritePnt ) */
366
f_pEventGetTone->fMoreEvents = FALSE;
368
/* Remember this state in the interrupt manager. */
369
pSharedInfo->IntrptManage.fToneEventsPending = FALSE;
372
f_pEventGetTone->ulNumValidToneEvent = ulNumEventsReturned;
377
f_pEventGetTone->ulNumValidToneEvent = 0;
378
f_pEventGetTone->fMoreEvents = FALSE;
380
/* Remember this state in the interrupt manager. */
381
pSharedInfo->IntrptManage.fToneEventsPending = FALSE;
383
return cOCT6100_ERR_EVENTS_TONE_BUF_EMPTY;
386
else /* ( f_pEventGetTone->fResetBufs == TRUE ) */
388
/* Empty the hardware buffer. */
389
ulResult = Oct6100ApiTransferToneEvents( f_pApiInstance, f_pEventGetTone->fResetBufs );
390
if ( ulResult != cOCT6100_ERR_OK )
393
/* If the buffers are to be reset then update the pointers and full flag. */
394
pSharedInfo->SoftBufs.ulToneEventBufferReadPtr = 0;
395
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0;
397
f_pEventGetTone->fMoreEvents = FALSE;
398
f_pEventGetTone->ulNumValidToneEvent = 0;
400
/* Remember this state in the interrupt manager. */
401
pSharedInfo->IntrptManage.fToneEventsPending = FALSE;
404
return cOCT6100_ERR_OK;
409
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
411
Function: Oct6100ApiTransferToneEvents
413
Description: Transfers all tone events from the PGSP event out chip buffer
416
-------------------------------------------------------------------------------
417
| Argument | Description
418
-------------------------------------------------------------------------------
419
f_pApiInstance Pointer to API instance. This memory is used to keep
420
the present state of the chip and all its resources.
422
f_ulResetBuf Reset flag.
424
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
425
#if !SKIP_Oct6100ApiTransferToneEvents
426
UINT32 Oct6100ApiTransferToneEvents(
427
IN OUT tPOCT6100_INSTANCE_API f_pApiInstance,
428
IN UINT32 f_ulResetBuf )
430
tPOCT6100_SHARED_INFO pSharedInfo;
431
tPOCT6100_API_TONE_EVENT pSoftEvent;
432
tPOCT6100_API_CHANNEL pEchoChannel;
433
tOCT6100_WRITE_PARAMS WriteParams;
434
tOCT6100_READ_PARAMS ReadParams;
435
tOCT6100_READ_BURST_PARAMS BurstParams;
436
UINT32 ulChipBufFill;
437
UINT32 ulChipWritePtr = 0;
438
UINT32 ulChipReadPtr = 0;
440
UINT32 usChannelIndex;
441
UINT32 ulBaseTimestamp;
443
UINT32 ulNumWordsToRead;
448
UINT16 ausReadData[ cOCT6100_NUM_WORDS_PER_TONE_EVENT ];
450
UINT32 ulExtToneDetectionPort;
452
/* Get local pointer(s). */
453
pSharedInfo = f_pApiInstance->pSharedInfo;
455
/* If the buffer is to be reset then clear the overflow flag. */
456
if ( f_ulResetBuf == TRUE )
458
pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt = 0;
461
/* Set some parameters of read struct. */
462
ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
464
ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
465
ReadParams.pusReadData = &usReadData;
467
/* Get the current read pointer of the chip buffer. */
468
ReadParams.ulReadAddress = cOCT6100_TONE_EVENT_READ_PTR_REG;
469
mOCT6100_DRIVER_READ_API( ReadParams, ulResult )
470
if ( ulResult != cOCT6100_ERR_OK )
473
ulChipReadPtr = usReadData;
475
/* Now get the current write pointer. */
476
ReadParams.ulReadAddress = cOCT6100_TONE_EVENT_WRITE_PTR_REG;
477
mOCT6100_DRIVER_READ_API( ReadParams, ulResult )
478
if ( ulResult != cOCT6100_ERR_OK )
481
ulChipWritePtr = usReadData;
483
ulChipBufFill = (( ulChipWritePtr - ulChipReadPtr ) & ( cOCT6100_NUM_PGSP_EVENT_OUT - 1 ));
485
/* Set some parameters of write structs. */
486
WriteParams.pProcessContext = f_pApiInstance->pProcessContext;
488
WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
490
BurstParams.pProcessContext = f_pApiInstance->pProcessContext;
492
BurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
494
/* Read in the tone event one at a time. */
495
for ( i = 0; i < ulChipBufFill; i++ )
497
/* Skip the event processing if the buffer is to be reset. */
498
if ( f_ulResetBuf == TRUE )
500
/* Update the control variables of the buffer. */
502
if ( cOCT6100_NUM_PGSP_EVENT_OUT == ulChipReadPtr )
507
/* Read in the event only if there's enough room in the soft buffer, and */
508
/* the chip buffer is NOT to be reset. */
509
if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) &&
510
((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) )
512
BurstParams.ulReadAddress = cOCT6100_PGSP_EVENT_OUT_BASE + ( ulChipReadPtr * cOCT6100_PGSP_TONE_EVENT_SIZE );
513
BurstParams.pusReadData = ausReadData;
515
ulNumWordsToRead = cOCT6100_PGSP_TONE_EVENT_SIZE / 2;
517
while ( ulNumWordsToRead > 0 )
519
if ( ulNumWordsToRead > pSharedInfo->ChipConfig.usMaxRwAccesses )
521
BurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses;
525
BurstParams.ulReadLength = ulNumWordsToRead;
528
mOCT6100_DRIVER_READ_BURST_API( BurstParams, ulResult );
529
if ( ulResult != cOCT6100_ERR_OK )
532
BurstParams.pusReadData += BurstParams.ulReadLength;
533
BurstParams.ulReadAddress += BurstParams.ulReadLength * 2;
535
ulNumWordsToRead -= BurstParams.ulReadLength;
538
/* Verify if the event is valid. */
539
if ( ( ausReadData[ 0 ] & cOCT6100_VALID_TONE_EVENT ) == 0x0 )
540
return cOCT6100_ERR_FATAL_2D;
542
/* First extract the channel number of the tone event. */
543
usChannelIndex = ausReadData[ 1 ] & 0x3FF;
545
/* Now the timestamp. */
546
ulBaseTimestamp = ausReadData[ 2 ] << 16;
547
ulBaseTimestamp |= ausReadData[ 3 ];
549
/* This timestamp is 256 in adwance, must remove 256 frames. */
550
ulBaseTimestamp -= 256;
552
/* Fetch the channel stucture to validate which event can be reported. */
553
mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, usChannelIndex );
555
if ( pEchoChannel->fReserved != TRUE )
557
/* Update the control variables of the buffer. */
559
if ( ulChipReadPtr == cOCT6100_NUM_PGSP_EVENT_OUT )
562
/* This channel has been closed since the generation of the event. */
566
/* Extract the extended tone detection port if available. */
567
if ( pEchoChannel->ulExtToneChanMode == cOCT6100_API_EXT_TONE_SIN_PORT_MODE )
569
ulExtToneDetectionPort = cOCT6100_CHANNEL_PORT_SIN;
571
else if ( pEchoChannel->ulExtToneChanMode == cOCT6100_API_EXT_TONE_RIN_PORT_MODE )
573
ulExtToneDetectionPort = cOCT6100_CHANNEL_PORT_RIN;
575
/* Modify the channel index. */
576
usChannelIndex = pEchoChannel->usExtToneChanIndex;
578
/* Change the channel entry to the original one for statistical purposes. */
579
mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, usChannelIndex );
582
else /* pEchoChannel->ulExtToneChanMode == cOCT6100_API_EXT_TONE_DISABLED */
584
ulExtToneDetectionPort = cOCT6100_INVALID_VALUE;
588
/* Verify all the possible events that might have been detected. */
589
for ( j = 4; j < cOCT6100_NUM_WORDS_PER_TONE_EVENT; j++ )
591
if ( (( ausReadData[ j ] >> 8 ) & 0x7 ) != 0x0 )
593
/* This tone generated an event, now check if event is masked for the channel. */
594
if ((( pEchoChannel->aulToneConf[ ulToneCnt / 32 ] >> ( 31 - ( ulToneCnt % 32 ))) & 0x1) == 1 )
596
/* If enough space. */
597
if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) &&
598
((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) )
600
/* The tone event is not masked, The API can create a soft tone event. */
601
mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
602
pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
604
/* Decode the event type. */
605
switch(( ausReadData[ j ] >> 8 ) & 0x7 )
608
pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
611
pSoftEvent->ulEventType = cOCT6100_TONE_STOP;
614
/* This one is a little tricky. We first */
615
/* generate the "PRESENT" event and then generate the "STOP" event. */
617
pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
618
pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | usChannelIndex;
619
pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId;
620
pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID;
621
/* We want the timestamp not to be equal to the "STOP" event, so we subtract one to the detector's value. */
622
pSoftEvent->ulTimestamp = ( ulBaseTimestamp + ((( ausReadData[ j ] >> 13 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT ) ) - 1;
623
pSoftEvent->ulExtToneDetectionPort = ulExtToneDetectionPort;
625
/* Update the control variables of the buffer. */
626
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++;
627
if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize )
628
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0;
630
/* If enough space for the "STOP" event. */
631
if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) &&
632
((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) )
634
mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
635
pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
637
pSoftEvent->ulEventType = cOCT6100_TONE_STOP;
641
/* Set the overflow flag of the buffer. */
642
pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
644
/* We continue in the loop in order to empty the hardware buffer. */
650
pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
653
pSharedInfo->ErrorStats.ulToneDetectorErrorCnt++;
654
/* do not process this packet*/
658
pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | usChannelIndex;
659
pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId;
660
pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID;
661
pSoftEvent->ulTimestamp = ulBaseTimestamp + ((( ausReadData[ j ] >> 13 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT );
662
pSoftEvent->ulExtToneDetectionPort = ulExtToneDetectionPort;
664
/* Update the control variables of the buffer. */
665
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++;
666
if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize )
667
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0;
669
/* Set the interrupt manager such that the user knows that some tone events */
670
/* are pending in the software Q. */
671
pSharedInfo->IntrptManage.fToneEventsPending = TRUE;
675
/* Set the overflow flag of the buffer. */
676
pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
678
/* We continue in the loop in order to empty the hardware buffer. */
685
ulResult = Oct6100ApiIsSSTone(
687
pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID,
689
if ( ulResult != cOCT6100_ERR_OK )
692
if ( fSSTone == TRUE )
694
/* Check if this is a "PRESENT" or "STOP" event */
695
switch( ( ( ausReadData[ j ] >> 8 ) & 0x7 ) )
698
/* This is a signaling system present event. Keep this in the instance memory. */
699
pEchoChannel->ulLastSSToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID;
700
pEchoChannel->ulLastSSToneTimestamp = ulBaseTimestamp + ((( ausReadData[ j ] >> 13 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT );
703
/* This is the "STOP" event, invalidate the last value. The user does not want to know about this. */
704
pEchoChannel->ulLastSSToneDetected = cOCT6100_INVALID_VALUE;
705
pEchoChannel->ulLastSSToneTimestamp = cOCT6100_INVALID_VALUE;
715
/* Check the other tone of this word. */
716
if ( ( ausReadData[ j ] & 0x7 ) != 0x0 )
718
if ((( pEchoChannel->aulToneConf[ ulToneCnt / 32 ] >> ( 31 - ( ulToneCnt % 32 ))) & 0x1) == 1 )
720
/* If enough space. */
721
if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) &&
722
((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) )
724
/* The tone event is not masked, The API can create a soft tone event. */
725
mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
726
pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
728
/* Decode the event type. */
729
switch(( ausReadData[ j ] ) & 0x7 )
732
pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
735
pSoftEvent->ulEventType = cOCT6100_TONE_STOP;
738
/* This one is a little tricky. We first */
739
/* generate the "PRESENT" event and then generate the "STOP" event. */
741
pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
742
pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | usChannelIndex;
743
pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId;
744
pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID;
745
/* We want the timestamp not to be equal to the "STOP" event, so we subtract one to the detector's value. */
746
pSoftEvent->ulTimestamp = ( ulBaseTimestamp + ((( ausReadData[ j ] >> 5 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT ) ) - 1;
747
pSoftEvent->ulExtToneDetectionPort = ulExtToneDetectionPort;
749
/* Update the control variables of the buffer. */
750
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++;
751
if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize )
752
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0;
754
/* If enough space for the "STOP" event. */
755
if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) &&
756
((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) )
758
mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
759
pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
761
pSoftEvent->ulEventType = cOCT6100_TONE_STOP;
765
/* Set the overflow flag of the buffer. */
766
pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
768
/* We continue in the loop in order to empty the hardware buffer. */
774
pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
777
pSharedInfo->ErrorStats.ulToneDetectorErrorCnt++;
778
/* Do not process this packet. */
782
pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | usChannelIndex;
783
pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId;
784
pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID;
785
pSoftEvent->ulTimestamp = ulBaseTimestamp + ((( ausReadData[ j ] >> 5 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT );
786
pSoftEvent->ulExtToneDetectionPort = ulExtToneDetectionPort;
788
/* Update the control variables of the buffer. */
789
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++;
790
if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize )
791
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0;
793
/* Set the interrupt manager such that the user knows that some tone events */
794
/* are pending in the software Q. */
795
pSharedInfo->IntrptManage.fToneEventsPending = TRUE;
800
/* Set the overflow flag of the buffer. */
801
pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
803
/* We continue in the loop in order to empty the hardware buffer. */
810
ulResult = Oct6100ApiIsSSTone(
812
pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID,
814
if ( ulResult != cOCT6100_ERR_OK )
817
if ( fSSTone == TRUE )
819
/* Check if this is a "PRESENT" event. */
820
switch ( ( ausReadData[ j ] ) & 0x7 )
823
/* This is a signaling system present event. Keep this in the instance memory. */
824
pEchoChannel->ulLastSSToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID;
825
pEchoChannel->ulLastSSToneTimestamp = ulBaseTimestamp + ((( ausReadData[ j ] >> 5 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT );
828
/* This is the "STOP" event, invalidate the last value. The user does not want to know about this. */
829
pEchoChannel->ulLastSSToneDetected = cOCT6100_INVALID_VALUE;
830
pEchoChannel->ulLastSSToneTimestamp = cOCT6100_INVALID_VALUE;
843
/* Set the overflow flag of the buffer. */
844
pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
846
/* We continue in the loop in order to empty the hardware buffer. */
849
/* Update the control variables of the buffer. */
851
if ( ulChipReadPtr == cOCT6100_NUM_PGSP_EVENT_OUT )
856
/* Write the value of the new Read pointer.*/
857
WriteParams.ulWriteAddress = cOCT6100_TONE_EVENT_READ_PTR_REG;
858
WriteParams.usWriteData = (UINT16)( ulChipReadPtr );
859
mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult )
860
if ( ulResult != cOCT6100_ERR_OK )
865
return cOCT6100_ERR_OK;
873
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
875
Function: Oct6100BufferPlayoutGetEventSer
877
Description: Retreives an array of buffer playout event from the software
880
-------------------------------------------------------------------------------
881
| Argument | Description
882
-------------------------------------------------------------------------------
883
f_pApiInstance Pointer to API instance. This memory is used to keep
884
the present state of the chip and all its resources.
886
f_pEventGetPlayoutStop Pointer to structure which will contain the retreived
889
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
890
#if !SKIP_Oct6100BufferPlayoutGetEventSer
891
UINT32 Oct6100BufferPlayoutGetEventSer(
892
IN OUT tPOCT6100_INSTANCE_API f_pApiInstance,
893
IN OUT tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent )
895
tPOCT6100_SHARED_INFO pSharedInfo;
896
tPOCT6100_API_BUFFER_PLAYOUT_EVENT pSoftEvent;
897
UINT32 ulSoftReadPnt;
898
UINT32 ulSoftWritePnt;
899
UINT32 ulSoftBufSize;
900
UINT32 ulNumEventsReturned;
903
/* Get local pointer(s). */
904
pSharedInfo = f_pApiInstance->pSharedInfo;
906
/* Check the parameters past by the user. */
907
if ( f_pBufPlayoutGetEvent->fResetBufs != TRUE &&
908
f_pBufPlayoutGetEvent->fResetBufs != FALSE )
909
return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_RESET;
911
/* Check if software buffer has been allocated and thus enabled. */
912
if ( pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize == 0 )
913
return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_DISABLED;
915
/* Checking max playout events. */
916
if ( f_pBufPlayoutGetEvent->ulMaxEvent > pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize )
917
return cOCT6100_ERR_BUFFER_PLAYOUT_MAX_EVENT;
919
if ( f_pBufPlayoutGetEvent->fResetBufs == FALSE )
921
/* Check if events need to be fetched from the chip. */
922
ulSoftReadPnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr;
923
ulSoftWritePnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr;
925
if ( ulSoftReadPnt == ulSoftWritePnt )
927
ulResult = Oct6100BufferPlayoutTransferEvents( f_pApiInstance, f_pBufPlayoutGetEvent->fResetBufs );
928
if ( ulResult != cOCT6100_ERR_OK )
932
/* If there are no events in the soft buffer then there are none in the chip */
933
/* either, so return the empty case. Else, return the events in the buffer. */
934
ulSoftReadPnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr;
935
ulSoftWritePnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr;
936
ulSoftBufSize = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferSize;
938
if ( ulSoftReadPnt != ulSoftWritePnt )
940
ulNumEventsReturned = 0;
942
while( (ulSoftReadPnt != ulSoftWritePnt) && ( ulNumEventsReturned != f_pBufPlayoutGetEvent->ulMaxEvent) )
944
/* Get a pointer to the first event in the buffer. */
945
mOCT6100_GET_BUFFER_PLAYOUT_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
946
pSoftEvent += ulSoftReadPnt;
948
f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulChannelHndl = pSoftEvent->ulChannelHandle;
949
f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulUserChanId = pSoftEvent->ulUserChanId;
950
f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulChannelPort = pSoftEvent->ulChannelPort;
951
f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulUserEventId = pSoftEvent->ulUserEventId;
952
f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulEventType = pSoftEvent->ulEventType;
953
f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulTimestamp = pSoftEvent->ulTimestamp;
955
/* Update the pointers of the soft buffer. */
957
if ( ulSoftReadPnt == ulSoftBufSize )
960
ulNumEventsReturned++;
963
pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr = ulSoftReadPnt;
965
/* Detemine if there are more events pending in the soft buffer. */
966
if ( ulSoftReadPnt != ulSoftWritePnt )
967
f_pBufPlayoutGetEvent->fMoreEvents = TRUE;
968
else /* ( ulSoftReadPnt == ulSoftWritePnt ) */
970
f_pBufPlayoutGetEvent->fMoreEvents = FALSE;
972
/* Remember this state in the interrupt manager. */
973
pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE;
976
f_pBufPlayoutGetEvent->ulNumValidEvent = ulNumEventsReturned;
978
else /* if ( ulSoftReadPnt == ulSoftWritePnt ) */
980
/* No valid buffer playout events. */
981
f_pBufPlayoutGetEvent->ulNumValidEvent = 0;
982
f_pBufPlayoutGetEvent->fMoreEvents = FALSE;
984
/* Remember this state in the interrupt manager. */
985
pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE;
987
return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_BUF_EMPTY;
990
else /* ( f_pEventGetPlayoutStop->fResetBufs == TRUE ) */
992
/* Check with the hardware first. */
993
ulResult = Oct6100BufferPlayoutTransferEvents( f_pApiInstance, f_pBufPlayoutGetEvent->fResetBufs );
994
if ( ulResult != cOCT6100_ERR_OK )
997
/* If the buffers are to be reset, then update the pointers and full flag. */
998
pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr = 0;
999
pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr = 0;
1001
f_pBufPlayoutGetEvent->fMoreEvents = FALSE;
1002
f_pBufPlayoutGetEvent->ulNumValidEvent = 0;
1004
/* Remember this state in the interrupt manager. */
1005
pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE;
1008
return cOCT6100_ERR_OK;
1013
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
1015
Function: Oct6100BufferPlayoutTransferEvents
1017
Description: Check all channels that are currently playing a buffer and
1018
generate an event if a buffer has stopped playing.
1020
-------------------------------------------------------------------------------
1021
| Argument | Description
1022
-------------------------------------------------------------------------------
1023
f_pApiInstance Pointer to API instance. This memory is used to keep
1024
the present state of the chip and all its resources.
1026
f_ulResetBuf Reset flag.
1028
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
1029
#if !SKIP_Oct6100BufferPlayoutTransferEvents
1030
UINT32 Oct6100BufferPlayoutTransferEvents(
1031
IN OUT tPOCT6100_INSTANCE_API f_pApiInstance,
1032
IN UINT32 f_ulResetBuf )
1034
tPOCT6100_SHARED_INFO pSharedInfo;
1035
tPOCT6100_API_CHANNEL pEchoChannel;
1037
UINT32 ulChannelIndex;
1039
UINT32 ulLastBufPlayoutEventBufferOverflowCnt;
1041
/* Get local pointer(s). */
1042
pSharedInfo = f_pApiInstance->pSharedInfo;
1044
/* If the buffer is to be reset then clear the overflow flag. */
1045
if ( f_ulResetBuf == TRUE )
1047
pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt = 0;
1048
/* We are done for now. */
1049
/* No need to check for new events since the user requested to empty the soft buffer. */
1050
return cOCT6100_ERR_OK;
1053
/* Check if buffer playout has been activated on some ports. */
1054
if ( pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts == 0 )
1056
/* Buffer playout has not been activated on any channel, */
1057
/* let's not waste time here. */
1058
return cOCT6100_ERR_OK;
1061
/* Save the current overflow count. We want to know if an overflow occured to get out of the loop. */
1062
ulLastBufPlayoutEventBufferOverflowCnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt;
1064
/* Search through the list of API channel entry for the ones that need playout event checking. */
1065
for ( ulChannelIndex = 0; ulChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; ulChannelIndex++ )
1067
mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, ulChannelIndex );
1069
/* Check if buffer playout is active on this channel, using the optimization flag. */
1070
/* This flag is redundant of other flags used for playout, but will make the above loop */
1071
/* much faster. This is needed since this function is called very frequently on systems */
1072
/* which use buffer playout stop events. */
1073
if ( pEchoChannel->fBufPlayoutActive == TRUE )
1075
/* Read in the event only if there's enough room in the soft buffer. */
1076
if ( ulLastBufPlayoutEventBufferOverflowCnt == pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt )
1078
/* Check Rout buffer playout first. */
1079
if ( ( pEchoChannel->fRinBufPlayoutNotifyOnStop == TRUE )
1080
&& ( pEchoChannel->fRinBufPlaying == TRUE ) )
1082
ulResult = Oct6100BufferPlayoutCheckForSpecificEvent( f_pApiInstance, ulChannelIndex, cOCT6100_CHANNEL_PORT_ROUT, TRUE, NULL );
1083
if ( ulResult != cOCT6100_ERR_OK )
1087
else /* if ( ulLastBufPlayoutEventBufferOverflowCnt != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt ) */
1089
/* Get out of the loop, no more events can be inserted in the soft buffer. */
1093
/* An overflow might have been detected in the lower level function. */
1094
/* Check the overflow count once again to make sure there might be room for a next event. */
1095
if ( ulLastBufPlayoutEventBufferOverflowCnt == pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt )
1097
/* Check Sout buffer playout. */
1098
if ( ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == TRUE )
1099
&& ( pEchoChannel->fSoutBufPlaying == TRUE ) )
1101
ulResult = Oct6100BufferPlayoutCheckForSpecificEvent( f_pApiInstance, ulChannelIndex, cOCT6100_CHANNEL_PORT_SOUT, TRUE, NULL );
1102
if ( ulResult != cOCT6100_ERR_OK )
1106
else /* if ( ulLastBufPlayoutEventBufferOverflowCnt != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt ) */
1108
/* Get out of the loop, no more events can be inserted in the soft buffer. */
1114
return cOCT6100_ERR_OK;
1119
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
1121
Function: Oct6100BufferPlayoutCheckForSpecificEvent
1123
Description: Check a specific channel/port for playout buffer events.
1124
If asked to, save this event to the software event buffer.
1125
Return a flag specifying whether the event was detected or not.
1127
-------------------------------------------------------------------------------
1128
| Argument | Description
1129
-------------------------------------------------------------------------------
1130
f_pApiInstance Pointer to API instance. This memory is used to keep
1131
the present state of the chip and all its resources.
1133
f_ulChannelIndex Index of the channel to be checked.
1134
f_ulChannelPort Port of the channel to be checked.
1135
f_fSaveToSoftBuffer Save event to software buffer.
1136
f_pfEventDetected Whether or not an event was detected.
1138
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
1139
#if !SKIP_Oct6100BufferPlayoutCheckForSpecificEvent
1140
UINT32 Oct6100BufferPlayoutCheckForSpecificEvent(
1141
IN OUT tPOCT6100_INSTANCE_API f_pApiInstance,
1142
IN UINT32 f_ulChannelIndex,
1143
IN UINT32 f_ulChannelPort,
1144
IN BOOL f_fSaveToSoftBuffer,
1145
OUT PBOOL f_pfEventDetected )
1147
tPOCT6100_SHARED_INFO pSharedInfo;
1148
tPOCT6100_API_BUFFER_PLAYOUT_EVENT pSoftEvent;
1149
tPOCT6100_API_CHANNEL pEchoChannel;
1150
tOCT6100_READ_PARAMS ReadParams;
1151
tOCT6100_GET_TIME GetTimeParms;
1155
UINT32 ulReadPtrBytesOfst;
1156
UINT32 ulReadPtrBitOfst;
1157
UINT32 ulReadPtrFieldSize;
1159
UINT32 ulWritePtrBytesOfst;
1160
UINT32 ulWritePtrBitOfst;
1161
UINT32 ulWritePtrFieldSize;
1163
UINT32 ulPlayoutBaseAddress;
1168
UINT32 ulUserEventId;
1171
/* Get local pointer(s). */
1172
pSharedInfo = f_pApiInstance->pSharedInfo;
1174
/* Compare the read and write pointers for matching. If they matched, playout stopped. */
1175
mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, f_ulChannelIndex );
1177
/* Set the playout feature base address. */
1178
ulPlayoutBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_ulChannelIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst;
1180
if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_ROUT )
1182
/* Check on the Rout port. */
1183
ulUserEventId = pEchoChannel->ulRinUserBufPlayoutEventId;
1184
ulEventType = pEchoChannel->byRinPlayoutStopEventType;
1186
ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.usDwordOffset * 4;
1187
ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byBitOffset;
1188
ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byFieldSize;
1190
ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.usDwordOffset * 4;
1191
ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byBitOffset;
1192
ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byFieldSize;
1194
else /* if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_SOUT ) */
1196
/* Check on the Sout port. */
1197
ulUserEventId = pEchoChannel->ulSoutUserBufPlayoutEventId;
1198
ulEventType = pEchoChannel->bySoutPlayoutStopEventType;
1200
ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.usDwordOffset * 4;
1201
ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byBitOffset;
1202
ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byFieldSize;
1204
ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.usDwordOffset * 4;
1205
ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byBitOffset;
1206
ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byFieldSize;
1209
/* Retrieve the current write pointer. */
1210
mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance,
1212
ulPlayoutBaseAddress + ulWritePtrBytesOfst,
1215
if ( ulResult != cOCT6100_ERR_OK )
1218
mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask );
1220
/* Store the write pointer.*/
1221
ulWritePtr = ( ulTempData & ulMask ) >> ulWritePtrBitOfst;
1223
/* Read the read pointer.*/
1224
ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
1226
ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
1227
ReadParams.pusReadData = &usReadData;
1228
ReadParams.ulReadAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst;
1230
/* Optimize this access by only reading the word we are interested in. */
1231
if ( ulReadPtrBitOfst < 16 )
1232
ReadParams.ulReadAddress += 2;
1234
/* Must read in memory directly since this value is changed by hardware */
1235
mOCT6100_DRIVER_READ_API( ReadParams, ulResult )
1236
if ( ulResult != cOCT6100_ERR_OK )
1239
/* Move data at correct position according to what was read. */
1240
if ( ulReadPtrBitOfst < 16 )
1241
ulTempData = usReadData;
1243
ulTempData = usReadData << 16;
1245
mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask );
1247
/* Store the read pointer. */
1248
ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst;
1250
/* Playout has finished when the read pointer reaches the write pointer. */
1251
if ( ulReadPtr != ulWritePtr )
1253
/* Still playing -- do not generate an event. */
1254
if ( f_pfEventDetected != NULL )
1255
*f_pfEventDetected = FALSE;
1259
/* Buffer stopped playing, generate an event here, if asked. */
1260
if ( ( f_fSaveToSoftBuffer == TRUE )
1261
&& ( ( pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr + 1 ) != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr )
1262
&& ( ( pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr + 1 ) != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferSize || pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr != 0 ) )
1264
/* The API can create a soft buffer playout event. */
1265
mOCT6100_GET_BUFFER_PLAYOUT_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
1266
pSoftEvent += pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr;
1268
pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_ulChannelIndex;
1269
pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId;
1270
pSoftEvent->ulUserEventId = ulUserEventId;
1271
pSoftEvent->ulChannelPort = f_ulChannelPort;
1272
/* For now, only this type of event is available. */
1273
pSoftEvent->ulEventType = ulEventType;
1275
/* Generate millisecond timestamp. */
1276
GetTimeParms.pProcessContext = f_pApiInstance->pProcessContext;
1277
ulResult = Oct6100UserGetTime( &GetTimeParms );
1278
if ( ulResult != cOCT6100_ERR_OK )
1281
pSoftEvent->ulTimestamp = ( GetTimeParms.aulWallTimeUs[ 0 ] / 1000 );
1282
pSoftEvent->ulTimestamp += ( GetTimeParms.aulWallTimeUs[ 1 ] ) * ( 0xFFFFFFFF / 1000 );
1284
/* Update the control variables of the buffer. */
1285
pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr++;
1286
if ( pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr == pSharedInfo->SoftBufs.ulBufPlayoutEventBufferSize )
1287
pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr = 0;
1289
/* Set the interrupt manager such that the user knows that some playout events */
1290
/* are pending in the software Q. */
1291
pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = TRUE;
1293
else if ( f_fSaveToSoftBuffer == TRUE )
1295
/* Set the overflow flag of the buffer. */
1296
pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt++;
1299
/* Update the channel entry to set the playing flag to FALSE. */
1301
/* Select the port of interest. */
1302
if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_ROUT )
1304
/* Decrement the number of active buffer playout ports. */
1305
/* No need to check anything here, it's been done in the calling function. */
1306
pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts--;
1308
pEchoChannel->fRinBufPlaying = FALSE;
1309
pEchoChannel->fRinBufPlayoutNotifyOnStop = FALSE;
1311
/* Clear optimization flag if possible. */
1312
if ( ( pEchoChannel->fSoutBufPlaying == FALSE )
1313
&& ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == FALSE ) )
1315
/* Buffer playout is no more active on this channel. */
1316
pEchoChannel->fBufPlayoutActive = FALSE;
1319
else /* f_ulChannelPort == cOCT6100_CHANNEL_PORT_SOUT */
1321
/* Decrement the number of active buffer playout ports. */
1322
/* No need to check anything here, it's been done in the calling function. */
1323
pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts--;
1325
pEchoChannel->fSoutBufPlaying = FALSE;
1326
pEchoChannel->fSoutBufPlayoutNotifyOnStop = FALSE;
1328
/* Clear optimization flag if possible. */
1329
if ( ( pEchoChannel->fRinBufPlaying == FALSE )
1330
&& ( pEchoChannel->fRinBufPlayoutNotifyOnStop == FALSE ) )
1332
/* Buffer playout is no more active on this channel. */
1333
pEchoChannel->fBufPlayoutActive = FALSE;
1337
/* Return that an event was detected. */
1338
if ( f_pfEventDetected != NULL )
1339
*f_pfEventDetected = TRUE;
1342
return cOCT6100_ERR_OK;
1346
#endif /* cOCT6100_REMOVE_EVENTS */