1
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
5
Copyright (c) 2001-2007 Octasic Inc.
9
This file contains functions used to retrieve tone and playout events.
11
This file is part of the Octasic OCT6100 GPL API . The OCT6100 GPL API is
12
free software; you can redistribute it and/or modify it under the terms of
13
the GNU General Public License as published by the Free Software Foundation;
14
either version 2 of the License, or (at your option) any later version.
16
The OCT6100 GPL API is distributed in the hope that it will be useful, but
17
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21
You should have received a copy of the GNU General Public License
22
along with the OCT6100 GPL API; if not, write to the Free Software
23
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
25
$Octasic_Release: OCT612xAPI-01.00-PR49 $
27
$Octasic_Revision: 81 $
29
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
32
/***************************** INCLUDE FILES *******************************/
36
#include "oct6100api/oct6100_defines.h"
37
#include "oct6100api/oct6100_errors.h"
38
#include "oct6100api/oct6100_apiud.h"
40
#include "apilib/octapi_llman.h"
42
#include "oct6100api/oct6100_tlv_inst.h"
43
#include "oct6100api/oct6100_chip_open_inst.h"
44
#include "oct6100api/oct6100_chip_stats_inst.h"
45
#include "oct6100api/oct6100_interrupts_inst.h"
46
#include "oct6100api/oct6100_remote_debug_inst.h"
47
#include "oct6100api/oct6100_debug_inst.h"
48
#include "oct6100api/oct6100_api_inst.h"
49
#include "oct6100api/oct6100_channel_inst.h"
50
#include "oct6100api/oct6100_events_inst.h"
51
#include "oct6100api/oct6100_tone_detection_inst.h"
52
#include "oct6100api/oct6100_playout_buf_inst.h"
54
#include "oct6100api/oct6100_interrupts_pub.h"
55
#include "oct6100api/oct6100_chip_open_pub.h"
56
#include "oct6100api/oct6100_channel_pub.h"
57
#include "oct6100api/oct6100_events_pub.h"
58
#include "oct6100api/oct6100_tone_detection_pub.h"
59
#include "oct6100api/oct6100_playout_buf_pub.h"
61
#include "oct6100_chip_open_priv.h"
62
#include "oct6100_miscellaneous_priv.h"
63
#include "oct6100_channel_priv.h"
64
#include "oct6100_events_priv.h"
65
#include "oct6100_tone_detection_priv.h"
66
#include "oct6100_playout_buf_priv.h"
68
/**************************** PUBLIC FUNCTIONS *****************************/
70
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
72
Function: Oct6100EventGetTone
74
Description: Retreives an array of tone events.
76
-------------------------------------------------------------------------------
77
| Argument | Description
78
-------------------------------------------------------------------------------
79
f_pApiInstance Pointer to API instance. This memory is used to keep
80
the present state of the chip and all its resources.
82
f_pEventGetTone Pointer to structure used to store the Tone events.
84
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
85
#if !SKIP_Oct6100EventGetToneDef
86
UINT32 Oct6100EventGetToneDef(
87
tPOCT6100_EVENT_GET_TONE f_pEventGetTone )
89
f_pEventGetTone->pToneEvent = NULL;
90
f_pEventGetTone->ulMaxToneEvent = 1;
91
f_pEventGetTone->ulNumValidToneEvent = cOCT6100_INVALID_VALUE;
92
f_pEventGetTone->fMoreEvents = FALSE;
93
f_pEventGetTone->fResetBufs = FALSE;
95
return cOCT6100_ERR_OK;
100
#if !SKIP_Oct6100EventGetTone
101
UINT32 Oct6100EventGetTone(
102
tPOCT6100_INSTANCE_API f_pApiInstance,
103
tPOCT6100_EVENT_GET_TONE f_pEventGetTone )
105
tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj;
106
tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj;
107
UINT32 ulSerRes = cOCT6100_ERR_OK;
108
UINT32 ulFncRes = cOCT6100_ERR_OK;
110
/* Set the process context of the serialize structure. */
111
SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext;
112
ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext;
114
/* Seize all list semaphores needed by this function. */
115
SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
116
SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY;
117
ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj );
118
if ( ulSerRes == cOCT6100_ERR_OK )
120
/* Call the serialized function. */
121
ulFncRes = Oct6100EventGetToneSer( f_pApiInstance, f_pEventGetTone );
128
/* Release the seized semaphores. */
129
ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
130
ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj );
132
/* If an error occured then return the error code. */
133
if ( ulSerRes != cOCT6100_ERR_OK )
135
if ( ulFncRes != cOCT6100_ERR_OK )
138
return cOCT6100_ERR_OK;
143
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
145
Function: Oct6100BufferPlayoutGetEvent
147
Description: Retrieves an array of playout stop events.
149
-------------------------------------------------------------------------------
150
| Argument | Description
151
-------------------------------------------------------------------------------
152
f_pApiInstance Pointer to API instance. This memory is used to keep
153
the present state of the chip and all its resources.
155
f_pBufPlayoutGetEvent Pointer to structure used to store the playout events.
157
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
158
#if !SKIP_Oct6100BufferPlayoutGetEventDef
159
UINT32 Oct6100BufferPlayoutGetEventDef(
160
tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent )
162
f_pBufPlayoutGetEvent->pBufferPlayoutEvent = NULL;
163
f_pBufPlayoutGetEvent->ulMaxEvent = 1;
164
f_pBufPlayoutGetEvent->ulNumValidEvent = cOCT6100_INVALID_VALUE;
165
f_pBufPlayoutGetEvent->fMoreEvents = FALSE;
166
f_pBufPlayoutGetEvent->fResetBufs = FALSE;
168
return cOCT6100_ERR_OK;
173
#if !SKIP_Oct6100BufferPlayoutGetEvent
174
UINT32 Oct6100BufferPlayoutGetEvent(
175
tPOCT6100_INSTANCE_API f_pApiInstance,
176
tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent )
178
tOCT6100_SEIZE_SERIALIZE_OBJECT SeizeSerObj;
179
tOCT6100_RELEASE_SERIALIZE_OBJECT ReleaseSerObj;
180
UINT32 ulSerRes = cOCT6100_ERR_OK;
181
UINT32 ulFncRes = cOCT6100_ERR_OK;
183
/* Set the process context of the serialize structure. */
184
SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext;
185
ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext;
187
/* Seize all list semaphores needed by this function. */
188
SeizeSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
189
SeizeSerObj.ulTryTimeMs = cOCT6100_WAIT_INFINITELY;
190
ulSerRes = Oct6100UserSeizeSerializeObject( &SeizeSerObj );
191
if ( ulSerRes == cOCT6100_ERR_OK )
193
/* Call the serialized function. */
194
ulFncRes = Oct6100BufferPlayoutGetEventSer( f_pApiInstance, f_pBufPlayoutGetEvent );
201
/* Release the seized semaphores. */
202
ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
203
ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj );
205
/* If an error occured then return the error code. */
206
if ( ulSerRes != cOCT6100_ERR_OK )
208
if ( ulFncRes != cOCT6100_ERR_OK )
211
return cOCT6100_ERR_OK;
216
/**************************** PRIVATE FUNCTIONS ****************************/
218
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
220
Function: Oct6100ApiGetEventsSwSizes
222
Description: Gets the sizes of all portions of the API instance pertinent
223
to the management of the tone events and playout events
226
-------------------------------------------------------------------------------
227
| Argument | Description
228
-------------------------------------------------------------------------------
229
f_pOpenChip Pointer to chip configuration struct.
230
f_pInstSizes Pointer to struct containing instance sizes.
232
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
233
#if !SKIP_Oct6100ApiGetEventsSwSizes
234
UINT32 Oct6100ApiGetEventsSwSizes(
235
IN tPOCT6100_CHIP_OPEN f_pOpenChip,
236
OUT tPOCT6100_API_INSTANCE_SIZES f_pInstSizes )
242
/* Memory needed by soft tone event buffers. */
244
/* Add 1 to the circular buffer such that all user requested events can fit in the circular queue. */
245
f_pInstSizes->ulSoftToneEventsBuffer = ( f_pOpenChip->ulSoftToneEventsBufSize + 1 ) * sizeof( tOCT6100_API_TONE_EVENT );
247
/* Round off the sizes of the soft buffers above. */
248
mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulSoftToneEventsBuffer, ulTempVar )
254
/* Memory needed by soft playout stop event buffers. */
255
if ( f_pOpenChip->ulSoftBufferPlayoutEventsBufSize != cOCT6100_INVALID_VALUE )
257
f_pInstSizes->ulSoftBufPlayoutEventsBuffer = ( f_pOpenChip->ulSoftBufferPlayoutEventsBufSize + 1 ) * sizeof( tOCT6100_API_BUFFER_PLAYOUT_EVENT );
259
/* Round off the sizes of the soft buffers above. */
260
mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulSoftBufPlayoutEventsBuffer, ulTempVar )
262
else /* if ( f_pInstSizes->ulSoftBufferPlayoutEventsBufSize == cOCT6100_INVALID_VALUE ) */
264
f_pInstSizes->ulSoftBufPlayoutEventsBuffer = 0;
268
return cOCT6100_ERR_OK;
273
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
275
Function: Oct6100EventGetToneSer
277
Description: Retreives an array of tone event from the software event buffer.
279
-------------------------------------------------------------------------------
280
| Argument | Description
281
-------------------------------------------------------------------------------
282
f_pApiInstance Pointer to API instance. This memory is used to keep
283
the present state of the chip and all its resources.
285
f_pEventGetTone Pointer to structure which will contain the retreived
288
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
289
#if !SKIP_Oct6100EventGetToneSer
290
UINT32 Oct6100EventGetToneSer(
291
IN OUT tPOCT6100_INSTANCE_API f_pApiInstance,
292
IN OUT tPOCT6100_EVENT_GET_TONE f_pEventGetTone )
294
tPOCT6100_SHARED_INFO pSharedInfo;
295
tPOCT6100_API_TONE_EVENT pSoftEvent;
296
UINT32 ulSoftReadPnt;
297
UINT32 ulSoftWritePnt;
298
UINT32 ulSoftBufSize;
299
UINT32 ulNumEventsReturned;
302
/* Get local pointer(s). */
303
pSharedInfo = f_pApiInstance->pSharedInfo;
305
/* Check the parameters given by the user. */
306
if ( f_pEventGetTone->fResetBufs != TRUE &&
307
f_pEventGetTone->fResetBufs != FALSE )
308
return cOCT6100_ERR_EVENTS_GET_TONE_RESET_BUFS;
310
/* Check max tones. */
311
if ( f_pEventGetTone->ulMaxToneEvent > pSharedInfo->ChipConfig.ulSoftToneEventsBufSize )
312
return cOCT6100_ERR_EVENTS_MAX_TONES;
314
if ( f_pEventGetTone->fResetBufs == FALSE )
316
/* Check if the events need to be fetched from the chip buffer. */
317
ulSoftReadPnt = pSharedInfo->SoftBufs.ulToneEventBufferReadPtr;
318
ulSoftWritePnt = pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
320
if ( ulSoftReadPnt == ulSoftWritePnt )
322
ulResult = Oct6100ApiTransferToneEvents( f_pApiInstance, f_pEventGetTone->fResetBufs );
323
if ( ulResult != cOCT6100_ERR_OK )
327
/* If there are no events in the soft buffer then there are none in the chip */
328
/* either, so return the empty case. Else, return the events in the buffer. */
329
ulSoftReadPnt = pSharedInfo->SoftBufs.ulToneEventBufferReadPtr;
330
ulSoftWritePnt = pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
331
ulSoftBufSize = pSharedInfo->SoftBufs.ulToneEventBufferSize;
333
if ( ulSoftReadPnt != ulSoftWritePnt )
335
ulNumEventsReturned = 0;
337
while( (ulSoftReadPnt != ulSoftWritePnt) && ( ulNumEventsReturned != f_pEventGetTone->ulMaxToneEvent) )
339
/* Get a pointer to the first event in the buffer. */
340
mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
341
pSoftEvent += ulSoftReadPnt;
343
f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulChannelHndl = pSoftEvent->ulChannelHandle;
344
f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulUserChanId = pSoftEvent->ulUserChanId;
345
f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulTimestamp = pSoftEvent->ulTimestamp;
346
f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulEventType = pSoftEvent->ulEventType;
347
f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulToneDetected = pSoftEvent->ulToneDetected;
348
f_pEventGetTone->pToneEvent[ ulNumEventsReturned ].ulExtToneDetectionPort = pSoftEvent->ulExtToneDetectionPort;
350
/* Update the pointers of the soft buffer. */
352
if ( ulSoftReadPnt == ulSoftBufSize )
355
ulNumEventsReturned++;
358
pSharedInfo->SoftBufs.ulToneEventBufferReadPtr = ulSoftReadPnt;
360
/* Detemine if there are more events pending in the soft buffer. */
361
if ( ulSoftReadPnt != ulSoftWritePnt )
362
f_pEventGetTone->fMoreEvents = TRUE;
363
else /* ( ulSoftReadPnt == ulSoftWritePnt ) */
365
f_pEventGetTone->fMoreEvents = FALSE;
367
/* Remember this state in the interrupt manager. */
368
pSharedInfo->IntrptManage.fToneEventsPending = FALSE;
371
f_pEventGetTone->ulNumValidToneEvent = ulNumEventsReturned;
376
f_pEventGetTone->ulNumValidToneEvent = 0;
377
f_pEventGetTone->fMoreEvents = FALSE;
379
/* Remember this state in the interrupt manager. */
380
pSharedInfo->IntrptManage.fToneEventsPending = FALSE;
382
return cOCT6100_ERR_EVENTS_TONE_BUF_EMPTY;
385
else /* ( f_pEventGetTone->fResetBufs == TRUE ) */
387
/* Empty the hardware buffer. */
388
ulResult = Oct6100ApiTransferToneEvents( f_pApiInstance, f_pEventGetTone->fResetBufs );
389
if ( ulResult != cOCT6100_ERR_OK )
392
/* If the buffers are to be reset then update the pointers and full flag. */
393
pSharedInfo->SoftBufs.ulToneEventBufferReadPtr = 0;
394
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0;
396
f_pEventGetTone->fMoreEvents = FALSE;
397
f_pEventGetTone->ulNumValidToneEvent = 0;
399
/* Remember this state in the interrupt manager. */
400
pSharedInfo->IntrptManage.fToneEventsPending = FALSE;
403
return cOCT6100_ERR_OK;
408
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
410
Function: Oct6100ApiTransferToneEvents
412
Description: Transfers all tone events from the PGSP event out chip buffer
415
-------------------------------------------------------------------------------
416
| Argument | Description
417
-------------------------------------------------------------------------------
418
f_pApiInstance Pointer to API instance. This memory is used to keep
419
the present state of the chip and all its resources.
421
f_ulResetBuf Reset flag.
423
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
424
#if !SKIP_Oct6100ApiTransferToneEvents
425
UINT32 Oct6100ApiTransferToneEvents(
426
IN OUT tPOCT6100_INSTANCE_API f_pApiInstance,
427
IN UINT32 f_ulResetBuf )
429
tPOCT6100_SHARED_INFO pSharedInfo;
430
tPOCT6100_API_TONE_EVENT pSoftEvent;
431
tPOCT6100_API_CHANNEL pEchoChannel;
432
tOCT6100_WRITE_PARAMS WriteParams;
433
tOCT6100_READ_PARAMS ReadParams;
434
tOCT6100_READ_BURST_PARAMS BurstParams;
435
UINT32 ulChipBufFill;
436
UINT32 ulChipWritePtr = 0;
437
UINT32 ulChipReadPtr = 0;
439
UINT32 usChannelIndex;
440
UINT32 ulBaseTimestamp;
442
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
ulEventCode = ( ausReadData[ j ] >> 8 ) & 0x7;
593
if ( ulEventCode != 0x0 )
595
/* This tone generated an event, now check if event is masked for the channel. */
596
if ((( pEchoChannel->aulToneConf[ ulToneCnt / 32 ] >> ( 31 - ( ulToneCnt % 32 ))) & 0x1) == 1 )
600
/* Check if it is a 2100 Tone STOP and if the user wants receive those events*/
601
ulResult = Oct6100ApiIs2100Tone(f_pApiInstance,
602
pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID,
604
if ( ulResult != cOCT6100_ERR_OK )
607
if ( (f2100Tone == FALSE) ||
608
( (f2100Tone == TRUE) && (ulEventCode != 2) ) ||
609
( (f2100Tone == TRUE) && pSharedInfo->ChipConfig.fEnable2100StopEvent == TRUE ) )
612
/* If enough space. */
613
if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) &&
614
((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) )
616
/* The tone event is not masked, The API can create a soft tone event. */
617
mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
618
pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
620
/* Decode the event type. */
621
switch( ulEventCode )
624
pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
627
pSoftEvent->ulEventType = cOCT6100_TONE_STOP;
630
/* This one is a little tricky. We first */
631
/* generate the "PRESENT" event and then generate the "STOP" event. */
633
pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
634
pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | usChannelIndex;
635
pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId;
636
pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID;
637
/* We want the timestamp not to be equal to the "STOP" event, so we subtract one to the detector's value. */
638
pSoftEvent->ulTimestamp = ( ulBaseTimestamp + ((( ausReadData[ j ] >> 13 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT ) ) - 1;
639
pSoftEvent->ulExtToneDetectionPort = ulExtToneDetectionPort;
641
/* Update the control variables of the buffer. */
642
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++;
643
if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize )
644
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0;
646
/* If enough space for the "STOP" event. */
647
if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) &&
648
((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) )
650
mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
651
pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
653
pSoftEvent->ulEventType = cOCT6100_TONE_STOP;
657
/* Set the overflow flag of the buffer. */
658
pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
660
/* We continue in the loop in order to empty the hardware buffer. */
666
pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
669
pSharedInfo->ErrorStats.ulToneDetectorErrorCnt++;
670
/* do not process this packet*/
674
pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | usChannelIndex;
675
pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId;
676
pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID;
677
pSoftEvent->ulTimestamp = ulBaseTimestamp + ((( ausReadData[ j ] >> 13 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT );
678
pSoftEvent->ulExtToneDetectionPort = ulExtToneDetectionPort;
680
/* Update the control variables of the buffer. */
681
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++;
682
if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize )
683
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0;
685
/* Set the interrupt manager such that the user knows that some tone events */
686
/* are pending in the software Q. */
687
pSharedInfo->IntrptManage.fToneEventsPending = TRUE;
691
/* Set the overflow flag of the buffer. */
692
pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
694
/* We continue in the loop in order to empty the hardware buffer. */
702
ulResult = Oct6100ApiIsSSTone(
704
pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID,
706
if ( ulResult != cOCT6100_ERR_OK )
709
if ( fSSTone == TRUE )
711
/* Check if this is a "PRESENT" or "STOP" event */
712
switch( ulEventCode )
715
/* This is a signaling system present event. Keep this in the instance memory. */
716
pEchoChannel->ulLastSSToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID;
717
pEchoChannel->ulLastSSToneTimestamp = ulBaseTimestamp + ((( ausReadData[ j ] >> 13 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT );
720
/* This is the "STOP" event, invalidate the last value. The user does not want to know about this. */
721
pEchoChannel->ulLastSSToneDetected = cOCT6100_INVALID_VALUE;
722
pEchoChannel->ulLastSSToneTimestamp = cOCT6100_INVALID_VALUE;
732
/* Check the other tone of this word. */
733
ulEventCode = ausReadData[ j ] & 0x7;
735
if ( ulEventCode != 0x0 )
737
if ((( pEchoChannel->aulToneConf[ ulToneCnt / 32 ] >> ( 31 - ( ulToneCnt % 32 ))) & 0x1) == 1 )
741
/* Check if it is a 2100 Tone STOP and if the user wants receive those events*/
742
ulResult = Oct6100ApiIs2100Tone(f_pApiInstance,
743
pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID,
745
if ( ulResult != cOCT6100_ERR_OK )
748
if ( (f2100Tone == FALSE) ||
749
( (f2100Tone == TRUE) && (ulEventCode != 2) ) ||
750
( (f2100Tone == TRUE) && pSharedInfo->ChipConfig.fEnable2100StopEvent == TRUE ) )
753
/* If enough space. */
754
if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) &&
755
((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) )
757
/* The tone event is not masked, The API can create a soft tone event. */
758
mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
759
pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
761
/* Decode the event type. */
762
switch( ulEventCode )
765
pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
768
pSoftEvent->ulEventType = cOCT6100_TONE_STOP;
771
/* This one is a little tricky. We first */
772
/* generate the "PRESENT" event and then generate the "STOP" event. */
774
pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
775
pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | usChannelIndex;
776
pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId;
777
pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID;
778
/* We want the timestamp not to be equal to the "STOP" event, so we subtract one to the detector's value. */
779
pSoftEvent->ulTimestamp = ( ulBaseTimestamp + ((( ausReadData[ j ] >> 5 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT ) ) - 1;
780
pSoftEvent->ulExtToneDetectionPort = ulExtToneDetectionPort;
782
/* Update the control variables of the buffer. */
783
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++;
784
if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize )
785
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0;
787
/* If enough space for the "STOP" event. */
788
if ( ((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferReadPtr) &&
789
((pSharedInfo->SoftBufs.ulToneEventBufferWritePtr + 1) != pSharedInfo->SoftBufs.ulToneEventBufferSize || pSharedInfo->SoftBufs.ulToneEventBufferReadPtr != 0) )
791
mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
792
pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
794
pSoftEvent->ulEventType = cOCT6100_TONE_STOP;
798
/* Set the overflow flag of the buffer. */
799
pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
801
/* We continue in the loop in order to empty the hardware buffer. */
807
pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
810
pSharedInfo->ErrorStats.ulToneDetectorErrorCnt++;
811
/* Do not process this packet. */
815
pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | usChannelIndex;
816
pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId;
817
pSoftEvent->ulToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID;
818
pSoftEvent->ulTimestamp = ulBaseTimestamp + ((( ausReadData[ j ] >> 5 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT );
819
pSoftEvent->ulExtToneDetectionPort = ulExtToneDetectionPort;
821
/* Update the control variables of the buffer. */
822
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr++;
823
if ( pSharedInfo->SoftBufs.ulToneEventBufferWritePtr == pSharedInfo->SoftBufs.ulToneEventBufferSize )
824
pSharedInfo->SoftBufs.ulToneEventBufferWritePtr = 0;
826
/* Set the interrupt manager such that the user knows that some tone events */
827
/* are pending in the software Q. */
828
pSharedInfo->IntrptManage.fToneEventsPending = TRUE;
833
/* Set the overflow flag of the buffer. */
834
pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
836
/* We continue in the loop in order to empty the hardware buffer. */
844
ulResult = Oct6100ApiIsSSTone(
846
pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID,
848
if ( ulResult != cOCT6100_ERR_OK )
851
if ( fSSTone == TRUE )
853
/* Check if this is a "PRESENT" event. */
854
switch ( ulEventCode )
857
/* This is a signaling system present event. Keep this in the instance memory. */
858
pEchoChannel->ulLastSSToneDetected = pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID;
859
pEchoChannel->ulLastSSToneTimestamp = ulBaseTimestamp + ((( ausReadData[ j ] >> 5 ) & 0x7) * cOCT6100_LOCAL_TIMESTAMP_INCREMENT );
862
/* This is the "STOP" event, invalidate the last value. The user does not want to know about this. */
863
pEchoChannel->ulLastSSToneDetected = cOCT6100_INVALID_VALUE;
864
pEchoChannel->ulLastSSToneTimestamp = cOCT6100_INVALID_VALUE;
877
/* Set the overflow flag of the buffer. */
878
pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
880
/* We continue in the loop in order to empty the hardware buffer. */
883
/* Update the control variables of the buffer. */
885
if ( ulChipReadPtr == cOCT6100_NUM_PGSP_EVENT_OUT )
890
/* Write the value of the new Read pointer.*/
891
WriteParams.ulWriteAddress = cOCT6100_TONE_EVENT_READ_PTR_REG;
892
WriteParams.usWriteData = (UINT16)( ulChipReadPtr );
893
mOCT6100_DRIVER_WRITE_API( WriteParams, ulResult )
894
if ( ulResult != cOCT6100_ERR_OK )
899
return cOCT6100_ERR_OK;
907
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
909
Function: Oct6100BufferPlayoutGetEventSer
911
Description: Retreives an array of buffer playout event from the software
914
-------------------------------------------------------------------------------
915
| Argument | Description
916
-------------------------------------------------------------------------------
917
f_pApiInstance Pointer to API instance. This memory is used to keep
918
the present state of the chip and all its resources.
920
f_pEventGetPlayoutStop Pointer to structure which will contain the retreived
923
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
924
#if !SKIP_Oct6100BufferPlayoutGetEventSer
925
UINT32 Oct6100BufferPlayoutGetEventSer(
926
IN OUT tPOCT6100_INSTANCE_API f_pApiInstance,
927
IN OUT tPOCT6100_BUFFER_PLAYOUT_GET_EVENT f_pBufPlayoutGetEvent )
929
tPOCT6100_SHARED_INFO pSharedInfo;
930
tPOCT6100_API_BUFFER_PLAYOUT_EVENT pSoftEvent;
931
UINT32 ulSoftReadPnt;
932
UINT32 ulSoftWritePnt;
933
UINT32 ulSoftBufSize;
934
UINT32 ulNumEventsReturned;
937
/* Get local pointer(s). */
938
pSharedInfo = f_pApiInstance->pSharedInfo;
940
/* Check the parameters past by the user. */
941
if ( f_pBufPlayoutGetEvent->fResetBufs != TRUE &&
942
f_pBufPlayoutGetEvent->fResetBufs != FALSE )
943
return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_RESET;
945
/* Check if software buffer has been allocated and thus enabled. */
946
if ( pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize == 0 )
947
return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_DISABLED;
949
/* Checking max playout events. */
950
if ( f_pBufPlayoutGetEvent->ulMaxEvent > pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize )
951
return cOCT6100_ERR_BUFFER_PLAYOUT_MAX_EVENT;
953
if ( f_pBufPlayoutGetEvent->fResetBufs == FALSE )
955
/* Check if events need to be fetched from the chip. */
956
ulSoftReadPnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr;
957
ulSoftWritePnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr;
959
if ( ulSoftReadPnt == ulSoftWritePnt )
961
ulResult = Oct6100BufferPlayoutTransferEvents( f_pApiInstance, f_pBufPlayoutGetEvent->fResetBufs );
962
if ( ulResult != cOCT6100_ERR_OK )
966
/* If there are no events in the soft buffer then there are none in the chip */
967
/* either, so return the empty case. Else, return the events in the buffer. */
968
ulSoftReadPnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr;
969
ulSoftWritePnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr;
970
ulSoftBufSize = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferSize;
972
if ( ulSoftReadPnt != ulSoftWritePnt )
974
ulNumEventsReturned = 0;
976
while( (ulSoftReadPnt != ulSoftWritePnt) && ( ulNumEventsReturned != f_pBufPlayoutGetEvent->ulMaxEvent) )
978
/* Get a pointer to the first event in the buffer. */
979
mOCT6100_GET_BUFFER_PLAYOUT_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
980
pSoftEvent += ulSoftReadPnt;
982
f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulChannelHndl = pSoftEvent->ulChannelHandle;
983
f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulUserChanId = pSoftEvent->ulUserChanId;
984
f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulChannelPort = pSoftEvent->ulChannelPort;
985
f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulUserEventId = pSoftEvent->ulUserEventId;
986
f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulEventType = pSoftEvent->ulEventType;
987
f_pBufPlayoutGetEvent->pBufferPlayoutEvent[ ulNumEventsReturned ].ulTimestamp = pSoftEvent->ulTimestamp;
989
/* Update the pointers of the soft buffer. */
991
if ( ulSoftReadPnt == ulSoftBufSize )
994
ulNumEventsReturned++;
997
pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr = ulSoftReadPnt;
999
/* Detemine if there are more events pending in the soft buffer. */
1000
if ( ulSoftReadPnt != ulSoftWritePnt )
1001
f_pBufPlayoutGetEvent->fMoreEvents = TRUE;
1002
else /* ( ulSoftReadPnt == ulSoftWritePnt ) */
1004
f_pBufPlayoutGetEvent->fMoreEvents = FALSE;
1006
/* Remember this state in the interrupt manager. */
1007
pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE;
1010
f_pBufPlayoutGetEvent->ulNumValidEvent = ulNumEventsReturned;
1012
else /* if ( ulSoftReadPnt == ulSoftWritePnt ) */
1014
/* No valid buffer playout events. */
1015
f_pBufPlayoutGetEvent->ulNumValidEvent = 0;
1016
f_pBufPlayoutGetEvent->fMoreEvents = FALSE;
1018
/* Remember this state in the interrupt manager. */
1019
pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE;
1021
return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_BUF_EMPTY;
1024
else /* ( f_pEventGetPlayoutStop->fResetBufs == TRUE ) */
1026
/* Check with the hardware first. */
1027
ulResult = Oct6100BufferPlayoutTransferEvents( f_pApiInstance, f_pBufPlayoutGetEvent->fResetBufs );
1028
if ( ulResult != cOCT6100_ERR_OK )
1031
/* If the buffers are to be reset, then update the pointers and full flag. */
1032
pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr = 0;
1033
pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr = 0;
1035
f_pBufPlayoutGetEvent->fMoreEvents = FALSE;
1036
f_pBufPlayoutGetEvent->ulNumValidEvent = 0;
1038
/* Remember this state in the interrupt manager. */
1039
pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE;
1042
return cOCT6100_ERR_OK;
1047
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
1049
Function: Oct6100BufferPlayoutTransferEvents
1051
Description: Check all channels that are currently playing a buffer and
1052
generate an event if a buffer has stopped playing.
1054
-------------------------------------------------------------------------------
1055
| Argument | Description
1056
-------------------------------------------------------------------------------
1057
f_pApiInstance Pointer to API instance. This memory is used to keep
1058
the present state of the chip and all its resources.
1060
f_ulResetBuf Reset flag.
1062
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
1063
#if !SKIP_Oct6100BufferPlayoutTransferEvents
1064
UINT32 Oct6100BufferPlayoutTransferEvents(
1065
IN OUT tPOCT6100_INSTANCE_API f_pApiInstance,
1066
IN UINT32 f_ulResetBuf )
1068
tPOCT6100_SHARED_INFO pSharedInfo;
1069
tPOCT6100_API_CHANNEL pEchoChannel;
1071
UINT32 ulChannelIndex;
1073
UINT32 ulLastBufPlayoutEventBufferOverflowCnt;
1075
/* Get local pointer(s). */
1076
pSharedInfo = f_pApiInstance->pSharedInfo;
1078
/* If the buffer is to be reset then clear the overflow flag. */
1079
if ( f_ulResetBuf == TRUE )
1081
pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt = 0;
1082
/* We are done for now. */
1083
/* No need to check for new events since the user requested to empty the soft buffer. */
1084
return cOCT6100_ERR_OK;
1087
/* Check if buffer playout has been activated on some ports. */
1088
if ( pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts == 0 )
1090
/* Buffer playout has not been activated on any channel, */
1091
/* let's not waste time here. */
1092
return cOCT6100_ERR_OK;
1095
/* Save the current overflow count. We want to know if an overflow occured to get out of the loop. */
1096
ulLastBufPlayoutEventBufferOverflowCnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt;
1098
/* Search through the list of API channel entry for the ones that need playout event checking. */
1099
for ( ulChannelIndex = 0; ulChannelIndex < pSharedInfo->ChipConfig.usMaxChannels; ulChannelIndex++ )
1101
mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, ulChannelIndex );
1103
/* Check if buffer playout is active on this channel, using the optimization flag. */
1104
/* This flag is redundant of other flags used for playout, but will make the above loop */
1105
/* much faster. This is needed since this function is called very frequently on systems */
1106
/* which use buffer playout stop events. */
1107
if ( pEchoChannel->fBufPlayoutActive == TRUE )
1109
/* Read in the event only if there's enough room in the soft buffer. */
1110
if ( ulLastBufPlayoutEventBufferOverflowCnt == pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt )
1112
/* Check Rout buffer playout first. */
1113
if ( ( pEchoChannel->fRinBufPlayoutNotifyOnStop == TRUE )
1114
&& ( pEchoChannel->fRinBufPlaying == TRUE ) )
1116
ulResult = Oct6100BufferPlayoutCheckForSpecificEvent( f_pApiInstance, ulChannelIndex, cOCT6100_CHANNEL_PORT_ROUT, TRUE, NULL );
1117
if ( ulResult != cOCT6100_ERR_OK )
1121
else /* if ( ulLastBufPlayoutEventBufferOverflowCnt != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt ) */
1123
/* Get out of the loop, no more events can be inserted in the soft buffer. */
1127
/* An overflow might have been detected in the lower level function. */
1128
/* Check the overflow count once again to make sure there might be room for a next event. */
1129
if ( ulLastBufPlayoutEventBufferOverflowCnt == pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt )
1131
/* Check Sout buffer playout. */
1132
if ( ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == TRUE )
1133
&& ( pEchoChannel->fSoutBufPlaying == TRUE ) )
1135
ulResult = Oct6100BufferPlayoutCheckForSpecificEvent( f_pApiInstance, ulChannelIndex, cOCT6100_CHANNEL_PORT_SOUT, TRUE, NULL );
1136
if ( ulResult != cOCT6100_ERR_OK )
1140
else /* if ( ulLastBufPlayoutEventBufferOverflowCnt != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt ) */
1142
/* Get out of the loop, no more events can be inserted in the soft buffer. */
1148
return cOCT6100_ERR_OK;
1153
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
1155
Function: Oct6100BufferPlayoutCheckForSpecificEvent
1157
Description: Check a specific channel/port for playout buffer events.
1158
If asked to, save this event to the software event buffer.
1159
Return a flag specifying whether the event was detected or not.
1161
-------------------------------------------------------------------------------
1162
| Argument | Description
1163
-------------------------------------------------------------------------------
1164
f_pApiInstance Pointer to API instance. This memory is used to keep
1165
the present state of the chip and all its resources.
1167
f_ulChannelIndex Index of the channel to be checked.
1168
f_ulChannelPort Port of the channel to be checked.
1169
f_fSaveToSoftBuffer Save event to software buffer.
1170
f_pfEventDetected Whether or not an event was detected.
1172
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
1173
#if !SKIP_Oct6100BufferPlayoutCheckForSpecificEvent
1174
UINT32 Oct6100BufferPlayoutCheckForSpecificEvent(
1175
IN OUT tPOCT6100_INSTANCE_API f_pApiInstance,
1176
IN UINT32 f_ulChannelIndex,
1177
IN UINT32 f_ulChannelPort,
1178
IN BOOL f_fSaveToSoftBuffer,
1179
OUT PBOOL f_pfEventDetected )
1181
tPOCT6100_SHARED_INFO pSharedInfo;
1182
tPOCT6100_API_BUFFER_PLAYOUT_EVENT pSoftEvent;
1183
tPOCT6100_API_CHANNEL pEchoChannel;
1184
tOCT6100_READ_PARAMS ReadParams;
1185
tOCT6100_GET_TIME GetTimeParms;
1189
UINT32 ulReadPtrBytesOfst;
1190
UINT32 ulReadPtrBitOfst;
1191
UINT32 ulReadPtrFieldSize;
1193
UINT32 ulWritePtrBytesOfst;
1194
UINT32 ulWritePtrBitOfst;
1195
UINT32 ulWritePtrFieldSize;
1197
UINT32 ulPlayoutBaseAddress;
1202
UINT32 ulUserEventId;
1205
/* Get local pointer(s). */
1206
pSharedInfo = f_pApiInstance->pSharedInfo;
1208
/* Compare the read and write pointers for matching. If they matched, playout stopped. */
1209
mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, f_ulChannelIndex );
1211
/* Set the playout feature base address. */
1212
ulPlayoutBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_ulChannelIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst;
1214
if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_ROUT )
1216
/* Check on the Rout port. */
1217
ulUserEventId = pEchoChannel->ulRinUserBufPlayoutEventId;
1218
ulEventType = pEchoChannel->byRinPlayoutStopEventType;
1220
ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.usDwordOffset * 4;
1221
ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byBitOffset;
1222
ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byFieldSize;
1224
ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.usDwordOffset * 4;
1225
ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byBitOffset;
1226
ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byFieldSize;
1228
else /* if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_SOUT ) */
1230
/* Check on the Sout port. */
1231
ulUserEventId = pEchoChannel->ulSoutUserBufPlayoutEventId;
1232
ulEventType = pEchoChannel->bySoutPlayoutStopEventType;
1234
ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.usDwordOffset * 4;
1235
ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byBitOffset;
1236
ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byFieldSize;
1238
ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.usDwordOffset * 4;
1239
ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byBitOffset;
1240
ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byFieldSize;
1243
/* Retrieve the current write pointer. */
1244
mOCT6100_RETRIEVE_NLP_CONF_DWORD( f_pApiInstance,
1246
ulPlayoutBaseAddress + ulWritePtrBytesOfst,
1249
if ( ulResult != cOCT6100_ERR_OK )
1252
mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask );
1254
/* Store the write pointer.*/
1255
ulWritePtr = ( ulTempData & ulMask ) >> ulWritePtrBitOfst;
1257
/* Read the read pointer.*/
1258
ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
1260
ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
1261
ReadParams.pusReadData = &usReadData;
1262
ReadParams.ulReadAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst;
1264
/* Optimize this access by only reading the word we are interested in. */
1265
if ( ulReadPtrBitOfst < 16 )
1266
ReadParams.ulReadAddress += 2;
1268
/* Must read in memory directly since this value is changed by hardware */
1269
mOCT6100_DRIVER_READ_API( ReadParams, ulResult )
1270
if ( ulResult != cOCT6100_ERR_OK )
1273
/* Move data at correct position according to what was read. */
1274
if ( ulReadPtrBitOfst < 16 )
1275
ulTempData = usReadData;
1277
ulTempData = usReadData << 16;
1279
mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask );
1281
/* Store the read pointer. */
1282
ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst;
1284
/* Playout has finished when the read pointer reaches the write pointer. */
1285
if ( ulReadPtr != ulWritePtr )
1287
/* Still playing -- do not generate an event. */
1288
if ( f_pfEventDetected != NULL )
1289
*f_pfEventDetected = FALSE;
1293
/* Buffer stopped playing, generate an event here, if asked. */
1294
if ( ( f_fSaveToSoftBuffer == TRUE )
1295
&& ( ( pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr + 1 ) != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr )
1296
&& ( ( pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr + 1 ) != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferSize || pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr != 0 ) )
1298
/* The API can create a soft buffer playout event. */
1299
mOCT6100_GET_BUFFER_PLAYOUT_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
1300
pSoftEvent += pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr;
1302
pSoftEvent->ulChannelHandle = cOCT6100_HNDL_TAG_CHANNEL | (pEchoChannel->byEntryOpenCnt << cOCT6100_ENTRY_OPEN_CNT_SHIFT) | f_ulChannelIndex;
1303
pSoftEvent->ulUserChanId = pEchoChannel->ulUserChanId;
1304
pSoftEvent->ulUserEventId = ulUserEventId;
1305
pSoftEvent->ulChannelPort = f_ulChannelPort;
1306
/* For now, only this type of event is available. */
1307
pSoftEvent->ulEventType = ulEventType;
1309
/* Generate millisecond timestamp. */
1310
GetTimeParms.pProcessContext = f_pApiInstance->pProcessContext;
1311
ulResult = Oct6100UserGetTime( &GetTimeParms );
1312
if ( ulResult != cOCT6100_ERR_OK )
1315
pSoftEvent->ulTimestamp = ( GetTimeParms.aulWallTimeUs[ 0 ] / 1000 );
1316
pSoftEvent->ulTimestamp += ( GetTimeParms.aulWallTimeUs[ 1 ] ) * ( 0xFFFFFFFF / 1000 );
1318
/* Update the control variables of the buffer. */
1319
pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr++;
1320
if ( pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr == pSharedInfo->SoftBufs.ulBufPlayoutEventBufferSize )
1321
pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr = 0;
1323
/* Set the interrupt manager such that the user knows that some playout events */
1324
/* are pending in the software Q. */
1325
pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = TRUE;
1327
else if ( f_fSaveToSoftBuffer == TRUE )
1329
/* Set the overflow flag of the buffer. */
1330
pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt++;
1333
/* Update the channel entry to set the playing flag to FALSE. */
1335
/* Select the port of interest. */
1336
if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_ROUT )
1338
/* Decrement the number of active buffer playout ports. */
1339
/* No need to check anything here, it's been done in the calling function. */
1340
pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts--;
1342
pEchoChannel->fRinBufPlaying = FALSE;
1343
pEchoChannel->fRinBufPlayoutNotifyOnStop = FALSE;
1345
/* Clear optimization flag if possible. */
1346
if ( ( pEchoChannel->fSoutBufPlaying == FALSE )
1347
&& ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == FALSE ) )
1349
/* Buffer playout is no more active on this channel. */
1350
pEchoChannel->fBufPlayoutActive = FALSE;
1353
else /* f_ulChannelPort == cOCT6100_CHANNEL_PORT_SOUT */
1355
/* Decrement the number of active buffer playout ports. */
1356
/* No need to check anything here, it's been done in the calling function. */
1357
pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts--;
1359
pEchoChannel->fSoutBufPlaying = FALSE;
1360
pEchoChannel->fSoutBufPlayoutNotifyOnStop = FALSE;
1362
/* Clear optimization flag if possible. */
1363
if ( ( pEchoChannel->fRinBufPlaying == FALSE )
1364
&& ( pEchoChannel->fRinBufPlayoutNotifyOnStop == FALSE ) )
1366
/* Buffer playout is no more active on this channel. */
1367
pEchoChannel->fBufPlayoutActive = FALSE;
1371
/* Return that an event was detected. */
1372
if ( f_pfEventDetected != NULL )
1373
*f_pfEventDetected = TRUE;
1376
return cOCT6100_ERR_OK;