~ubuntu-branches/ubuntu/quantal/zaptel/quantal

« back to all changes in this revision

Viewing changes to oct612x/octdeviceapi/oct6100api/oct6100_api/oct6100_events.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Purcell
  • Date: 2006-10-24 22:41:01 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20061024224101-464p4n2jk16n1jrh
Tags: 1:1.2.10.dfsg-2
* bristuff-0.3.0-PRE-1v
* Remove redundant GPL LICENCE text

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef cOCT6100_REMOVE_EVENTS
 
2
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
3
 
 
4
File: oct6100_events.c
 
5
 
 
6
    Copyright (c) 2001-2006 Octasic Inc.
 
7
    
 
8
Description: 
 
9
 
 
10
        This file contains functions used to retrieve tone and playout events.
 
11
 
 
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.
 
16
 
 
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 
 
20
for more details. 
 
21
 
 
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.
 
25
 
 
26
$Octasic_Release: OCT612xAPI-01.00-PR43 $
 
27
 
 
28
$Octasic_Revision: 79 $
 
29
 
 
30
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
31
 
 
32
 
 
33
/*****************************  INCLUDE FILES  *******************************/
 
34
 
 
35
#include "octdef.h"
 
36
 
 
37
#include "oct6100api/oct6100_defines.h"
 
38
#include "oct6100api/oct6100_errors.h"
 
39
#include "oct6100api/oct6100_apiud.h"
 
40
 
 
41
#include "apilib/octapi_llman.h"
 
42
 
 
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"
 
54
 
 
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"
 
61
 
 
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"
 
68
 
 
69
/****************************  PUBLIC FUNCTIONS  *****************************/
 
70
 
 
71
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
72
 
 
73
Function:               Oct6100EventGetTone
 
74
 
 
75
Description:    Retreives an array of tone events.
 
76
 
 
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.
 
82
 
 
83
f_pEventGetTone                 Pointer to structure used to store the Tone events.                                             
 
84
 
 
85
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
86
#if !SKIP_Oct6100EventGetToneDef
 
87
UINT32 Oct6100EventGetToneDef(
 
88
                                tPOCT6100_EVENT_GET_TONE                f_pEventGetTone )
 
89
{
 
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;
 
95
 
 
96
        return cOCT6100_ERR_OK; 
 
97
}
 
98
#endif
 
99
 
 
100
 
 
101
#if !SKIP_Oct6100EventGetTone
 
102
UINT32 Oct6100EventGetTone(
 
103
                                tPOCT6100_INSTANCE_API                  f_pApiInstance,
 
104
                                tPOCT6100_EVENT_GET_TONE                f_pEventGetTone )
 
105
{
 
106
        tOCT6100_SEIZE_SERIALIZE_OBJECT         SeizeSerObj;
 
107
        tOCT6100_RELEASE_SERIALIZE_OBJECT       ReleaseSerObj;
 
108
        UINT32                                                          ulSerRes = cOCT6100_ERR_OK;
 
109
        UINT32                                                          ulFncRes = cOCT6100_ERR_OK;
 
110
 
 
111
        /* Set the process context of the serialize structure. */
 
112
        SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
113
        ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
114
 
 
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 )
 
120
        {
 
121
                /* Call the serialized function. */
 
122
                ulFncRes = Oct6100EventGetToneSer( f_pApiInstance, f_pEventGetTone );
 
123
        }
 
124
        else
 
125
        {
 
126
                return ulSerRes;
 
127
        }
 
128
 
 
129
        /* Release the seized semaphores. */
 
130
        ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
131
        ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj );
 
132
 
 
133
        /* If an error occured then return the error code. */
 
134
        if ( ulSerRes != cOCT6100_ERR_OK )
 
135
                return ulSerRes;
 
136
        if ( ulFncRes != cOCT6100_ERR_OK )
 
137
                return ulFncRes;
 
138
 
 
139
        return cOCT6100_ERR_OK;
 
140
}
 
141
#endif
 
142
 
 
143
 
 
144
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
145
 
 
146
Function:               Oct6100BufferPlayoutGetEvent
 
147
 
 
148
Description:    Retrieves an array of playout stop events.
 
149
 
 
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.
 
155
 
 
156
f_pBufPlayoutGetEvent   Pointer to structure used to store the playout events.
 
157
 
 
158
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
159
#if !SKIP_Oct6100BufferPlayoutGetEventDef
 
160
UINT32 Oct6100BufferPlayoutGetEventDef(
 
161
                                tPOCT6100_BUFFER_PLAYOUT_GET_EVENT      f_pBufPlayoutGetEvent )
 
162
{
 
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;
 
168
 
 
169
        return cOCT6100_ERR_OK; 
 
170
}
 
171
#endif
 
172
 
 
173
 
 
174
#if !SKIP_Oct6100BufferPlayoutGetEvent
 
175
UINT32 Oct6100BufferPlayoutGetEvent(
 
176
                                tPOCT6100_INSTANCE_API                                  f_pApiInstance,
 
177
                                tPOCT6100_BUFFER_PLAYOUT_GET_EVENT              f_pBufPlayoutGetEvent )
 
178
{
 
179
        tOCT6100_SEIZE_SERIALIZE_OBJECT         SeizeSerObj;
 
180
        tOCT6100_RELEASE_SERIALIZE_OBJECT       ReleaseSerObj;
 
181
        UINT32                                                          ulSerRes = cOCT6100_ERR_OK;
 
182
        UINT32                                                          ulFncRes = cOCT6100_ERR_OK;
 
183
 
 
184
        /* Set the process context of the serialize structure. */
 
185
        SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
186
        ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
187
 
 
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 )
 
193
        {
 
194
                /* Call the serialized function. */
 
195
                ulFncRes = Oct6100BufferPlayoutGetEventSer( f_pApiInstance, f_pBufPlayoutGetEvent );
 
196
        }
 
197
        else
 
198
        {
 
199
                return ulSerRes;
 
200
        }
 
201
 
 
202
        /* Release the seized semaphores. */
 
203
        ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
204
        ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj );
 
205
 
 
206
        /* If an error occured then return the error code. */
 
207
        if ( ulSerRes != cOCT6100_ERR_OK )
 
208
                return ulSerRes;
 
209
        if ( ulFncRes != cOCT6100_ERR_OK )
 
210
                return ulFncRes;
 
211
 
 
212
        return cOCT6100_ERR_OK;
 
213
}
 
214
#endif
 
215
 
 
216
 
 
217
/****************************  PRIVATE FUNCTIONS  ****************************/
 
218
 
 
219
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
220
 
 
221
Function:               Oct6100ApiGetEventsSwSizes
 
222
 
 
223
Description:    Gets the sizes of all portions of the API instance pertinent
 
224
                                to the management of the tone events and playout events
 
225
                                software buffers.
 
226
 
 
227
-------------------------------------------------------------------------------
 
228
|       Argument                |       Description
 
229
-------------------------------------------------------------------------------
 
230
f_pOpenChip                             Pointer to chip configuration struct.
 
231
f_pInstSizes                    Pointer to struct containing instance sizes.
 
232
 
 
233
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
234
#if !SKIP_Oct6100ApiGetEventsSwSizes
 
235
UINT32 Oct6100ApiGetEventsSwSizes(
 
236
                                IN              tPOCT6100_CHIP_OPEN                             f_pOpenChip,
 
237
                                OUT             tPOCT6100_API_INSTANCE_SIZES    f_pInstSizes )
 
238
{
 
239
 
 
240
        {
 
241
                UINT32  ulTempVar;
 
242
                
 
243
                /* Memory needed by soft tone event buffers. */
 
244
 
 
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 );
 
247
 
 
248
                /* Round off the sizes of the soft buffers above. */
 
249
                mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulSoftToneEventsBuffer, ulTempVar )
 
250
        }
 
251
 
 
252
        {
 
253
                UINT32  ulTempVar;
 
254
 
 
255
                /* Memory needed by soft playout stop event buffers. */
 
256
                if ( f_pOpenChip->ulSoftBufferPlayoutEventsBufSize != cOCT6100_INVALID_VALUE )
 
257
                {
 
258
                        f_pInstSizes->ulSoftBufPlayoutEventsBuffer = ( f_pOpenChip->ulSoftBufferPlayoutEventsBufSize + 1 ) * sizeof( tOCT6100_API_BUFFER_PLAYOUT_EVENT );
 
259
 
 
260
                        /* Round off the sizes of the soft buffers above. */
 
261
                        mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulSoftBufPlayoutEventsBuffer, ulTempVar )
 
262
                }
 
263
                else /* if ( f_pInstSizes->ulSoftBufferPlayoutEventsBufSize == cOCT6100_INVALID_VALUE ) */
 
264
                {
 
265
                        f_pInstSizes->ulSoftBufPlayoutEventsBuffer = 0;
 
266
                }
 
267
        }
 
268
 
 
269
        return cOCT6100_ERR_OK;
 
270
}
 
271
#endif
 
272
 
 
273
 
 
274
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
275
 
 
276
Function:               Oct6100EventGetToneSer
 
277
 
 
278
Description:    Retreives an array of tone event from the software event buffer.
 
279
 
 
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.
 
285
 
 
286
f_pEventGetTone                 Pointer to structure which will contain the retreived
 
287
                                                events.
 
288
 
 
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 )
 
294
{
 
295
        tPOCT6100_SHARED_INFO           pSharedInfo;
 
296
        tPOCT6100_API_TONE_EVENT        pSoftEvent;
 
297
        UINT32  ulSoftReadPnt;
 
298
        UINT32  ulSoftWritePnt;
 
299
        UINT32  ulSoftBufSize;
 
300
        UINT32  ulNumEventsReturned;
 
301
        UINT32  ulResult;
 
302
 
 
303
        /* Get local pointer(s). */
 
304
        pSharedInfo = f_pApiInstance->pSharedInfo;
 
305
 
 
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;
 
310
        
 
311
        /* Check max tones. */
 
312
        if ( f_pEventGetTone->ulMaxToneEvent > pSharedInfo->ChipConfig.ulSoftToneEventsBufSize )
 
313
                return cOCT6100_ERR_EVENTS_MAX_TONES;
 
314
 
 
315
        if ( f_pEventGetTone->fResetBufs == FALSE )
 
316
        {
 
317
                /* Check if the events need to be fetched from the chip buffer. */
 
318
                ulSoftReadPnt = pSharedInfo->SoftBufs.ulToneEventBufferReadPtr;
 
319
                ulSoftWritePnt = pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
 
320
 
 
321
                if ( ulSoftReadPnt == ulSoftWritePnt )
 
322
                {
 
323
                        ulResult = Oct6100ApiTransferToneEvents( f_pApiInstance, f_pEventGetTone->fResetBufs );
 
324
                        if ( ulResult != cOCT6100_ERR_OK )
 
325
                                return ulResult;
 
326
                }
 
327
 
 
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;
 
333
 
 
334
                if ( ulSoftReadPnt != ulSoftWritePnt )
 
335
                {
 
336
                        ulNumEventsReturned = 0;
 
337
 
 
338
                        while( (ulSoftReadPnt != ulSoftWritePnt) && ( ulNumEventsReturned != f_pEventGetTone->ulMaxToneEvent) )
 
339
                        {
 
340
                                /* Get a pointer to the first event in the buffer. */
 
341
                                mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
 
342
                                pSoftEvent += ulSoftReadPnt;
 
343
                                
 
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;
 
350
 
 
351
                                /* Update the pointers of the soft buffer. */
 
352
                                ulSoftReadPnt++;
 
353
                                if ( ulSoftReadPnt == ulSoftBufSize )
 
354
                                        ulSoftReadPnt = 0;
 
355
 
 
356
                                ulNumEventsReturned++;
 
357
                        }
 
358
 
 
359
                        pSharedInfo->SoftBufs.ulToneEventBufferReadPtr = ulSoftReadPnt;
 
360
 
 
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 ) */
 
365
                        {
 
366
                                f_pEventGetTone->fMoreEvents = FALSE;
 
367
                                
 
368
                                /* Remember this state in the interrupt manager. */
 
369
                                pSharedInfo->IntrptManage.fToneEventsPending = FALSE;
 
370
                        }
 
371
 
 
372
                        f_pEventGetTone->ulNumValidToneEvent = ulNumEventsReturned;
 
373
                }
 
374
                else
 
375
                {
 
376
                        /* No valid tone.*/
 
377
                        f_pEventGetTone->ulNumValidToneEvent = 0;
 
378
                        f_pEventGetTone->fMoreEvents = FALSE;
 
379
 
 
380
                        /* Remember this state in the interrupt manager. */
 
381
                        pSharedInfo->IntrptManage.fToneEventsPending = FALSE;
 
382
                        
 
383
                        return cOCT6100_ERR_EVENTS_TONE_BUF_EMPTY;
 
384
                }
 
385
        }
 
386
        else /* ( f_pEventGetTone->fResetBufs == TRUE ) */
 
387
        {
 
388
                /* Empty the hardware buffer. */
 
389
                ulResult = Oct6100ApiTransferToneEvents( f_pApiInstance, f_pEventGetTone->fResetBufs );
 
390
                if ( ulResult != cOCT6100_ERR_OK )
 
391
                        return ulResult;
 
392
 
 
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;
 
396
 
 
397
                f_pEventGetTone->fMoreEvents = FALSE;
 
398
                f_pEventGetTone->ulNumValidToneEvent = 0;
 
399
 
 
400
                /* Remember this state in the interrupt manager. */
 
401
                pSharedInfo->IntrptManage.fToneEventsPending = FALSE;
 
402
        }
 
403
 
 
404
        return cOCT6100_ERR_OK;
 
405
}
 
406
#endif
 
407
 
 
408
 
 
409
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
410
 
 
411
Function:               Oct6100ApiTransferToneEvents
 
412
 
 
413
Description:    Transfers all tone events from the PGSP event out chip buffer 
 
414
                                to the soft buffer.
 
415
 
 
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.
 
421
 
 
422
f_ulResetBuf                    Reset flag.
 
423
 
 
424
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
425
#if !SKIP_Oct6100ApiTransferToneEvents
 
426
UINT32 Oct6100ApiTransferToneEvents(
 
427
                                IN OUT  tPOCT6100_INSTANCE_API                  f_pApiInstance,
 
428
                                IN              UINT32                                                  f_ulResetBuf )
 
429
{
 
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;
 
439
        
 
440
        UINT32  usChannelIndex;
 
441
        UINT32  ulBaseTimestamp;
 
442
        UINT32  ulToneCnt;
 
443
        UINT32  ulNumWordsToRead;
 
444
 
 
445
        UINT32  ulResult;
 
446
        UINT32  i, j;
 
447
        UINT16  usReadData;
 
448
        UINT16  ausReadData[ cOCT6100_NUM_WORDS_PER_TONE_EVENT ];
 
449
 
 
450
        UINT32  ulExtToneDetectionPort;
 
451
 
 
452
        /* Get local pointer(s). */
 
453
        pSharedInfo = f_pApiInstance->pSharedInfo;
 
454
 
 
455
        /* If the buffer is to be reset then clear the overflow flag. */
 
456
        if ( f_ulResetBuf == TRUE )
 
457
        {
 
458
                pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt = 0;
 
459
        }
 
460
 
 
461
        /* Set some parameters of read struct. */
 
462
        ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
 
463
 
 
464
        ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
 
465
        ReadParams.pusReadData = &usReadData;
 
466
        
 
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 )
 
471
                return ulResult;
 
472
 
 
473
        ulChipReadPtr = usReadData;
 
474
 
 
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 )
 
479
                return ulResult;
 
480
 
 
481
        ulChipWritePtr = usReadData;
 
482
 
 
483
        ulChipBufFill = (( ulChipWritePtr - ulChipReadPtr ) & ( cOCT6100_NUM_PGSP_EVENT_OUT - 1 ));
 
484
 
 
485
        /* Set some parameters of write structs. */
 
486
        WriteParams.pProcessContext = f_pApiInstance->pProcessContext;
 
487
 
 
488
        WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
 
489
 
 
490
        BurstParams.pProcessContext = f_pApiInstance->pProcessContext;
 
491
 
 
492
        BurstParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
 
493
 
 
494
        /* Read in the tone event one at a time. */
 
495
        for ( i = 0; i < ulChipBufFill; i++ )
 
496
        {
 
497
                /* Skip the event processing if the buffer is to be reset. */
 
498
                if ( f_ulResetBuf == TRUE )
 
499
                {
 
500
                        /* Update the control variables of the buffer. */
 
501
                        ulChipReadPtr++;
 
502
                        if ( cOCT6100_NUM_PGSP_EVENT_OUT == ulChipReadPtr )
 
503
                                ulChipReadPtr = 0;
 
504
                }
 
505
                else
 
506
                {
 
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) )
 
511
                        {
 
512
                                BurstParams.ulReadAddress = cOCT6100_PGSP_EVENT_OUT_BASE + ( ulChipReadPtr * cOCT6100_PGSP_TONE_EVENT_SIZE );
 
513
                                BurstParams.pusReadData = ausReadData;
 
514
 
 
515
                                ulNumWordsToRead = cOCT6100_PGSP_TONE_EVENT_SIZE / 2;
 
516
                                
 
517
                                while ( ulNumWordsToRead > 0 )
 
518
                                {
 
519
                                        if ( ulNumWordsToRead > pSharedInfo->ChipConfig.usMaxRwAccesses )
 
520
                                        {                               
 
521
                                                BurstParams.ulReadLength = pSharedInfo->ChipConfig.usMaxRwAccesses;
 
522
                                        }
 
523
                                        else
 
524
                                        {
 
525
                                                BurstParams.ulReadLength = ulNumWordsToRead;
 
526
                                        }
 
527
 
 
528
                                        mOCT6100_DRIVER_READ_BURST_API( BurstParams, ulResult );
 
529
                                        if ( ulResult != cOCT6100_ERR_OK )
 
530
                                                return ulResult;
 
531
 
 
532
                                        BurstParams.pusReadData         += BurstParams.ulReadLength;
 
533
                                        BurstParams.ulReadAddress       += BurstParams.ulReadLength * 2;
 
534
 
 
535
                                        ulNumWordsToRead -= BurstParams.ulReadLength;
 
536
                                }
 
537
 
 
538
                                /* Verify if the event is valid. */
 
539
                                if ( ( ausReadData[ 0 ] & cOCT6100_VALID_TONE_EVENT ) == 0x0 )
 
540
                                        return cOCT6100_ERR_FATAL_2D;
 
541
 
 
542
                                /* First extract the channel number of the tone event. */
 
543
                                usChannelIndex = ausReadData[ 1 ] & 0x3FF;
 
544
 
 
545
                                /* Now the timestamp. */
 
546
                                ulBaseTimestamp  = ausReadData[ 2 ] << 16;
 
547
                                ulBaseTimestamp |= ausReadData[ 3 ];
 
548
                                
 
549
                                /* This timestamp is 256 in adwance, must remove 256 frames. */
 
550
                                ulBaseTimestamp -= 256;
 
551
 
 
552
                                /* Fetch the channel stucture to validate which event can be reported. */
 
553
                                mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, usChannelIndex );
 
554
 
 
555
                                if ( pEchoChannel->fReserved != TRUE )
 
556
                                {
 
557
                                        /* Update the control variables of the buffer. */
 
558
                                        ulChipReadPtr++;
 
559
                                        if ( ulChipReadPtr == cOCT6100_NUM_PGSP_EVENT_OUT )
 
560
                                                ulChipReadPtr = 0;
 
561
                                        
 
562
                                        /* This channel has been closed since the generation of the event. */
 
563
                                        continue;
 
564
                                }
 
565
 
 
566
                                /* Extract the extended tone detection port if available. */
 
567
                                if ( pEchoChannel->ulExtToneChanMode == cOCT6100_API_EXT_TONE_SIN_PORT_MODE )
 
568
                                {
 
569
                                        ulExtToneDetectionPort = cOCT6100_CHANNEL_PORT_SIN;
 
570
                                }
 
571
                                else if ( pEchoChannel->ulExtToneChanMode == cOCT6100_API_EXT_TONE_RIN_PORT_MODE )
 
572
                                {
 
573
                                        ulExtToneDetectionPort = cOCT6100_CHANNEL_PORT_RIN;
 
574
 
 
575
                                        /* Modify the channel index. */
 
576
                                        usChannelIndex = pEchoChannel->usExtToneChanIndex;
 
577
 
 
578
                                        /* Change the channel entry to the original one for statistical purposes. */
 
579
                                        mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pEchoChannel, usChannelIndex );
 
580
 
 
581
                                }
 
582
                                else /* pEchoChannel->ulExtToneChanMode == cOCT6100_API_EXT_TONE_DISABLED */
 
583
                                {
 
584
                                        ulExtToneDetectionPort = cOCT6100_INVALID_VALUE;
 
585
                                }
 
586
 
 
587
                                ulToneCnt = 0;
 
588
                                /* Verify all the possible events that might have been detected. */
 
589
                                for ( j = 4; j < cOCT6100_NUM_WORDS_PER_TONE_EVENT; j++ )
 
590
                                {
 
591
                                        if ( (( ausReadData[ j ] >> 8 ) & 0x7 ) != 0x0 )
 
592
                                        {
 
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 )
 
595
                                                {
 
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) )
 
599
                                                        {
 
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;
 
603
 
 
604
                                                                /* Decode the event type. */
 
605
                                                                switch(( ausReadData[ j ] >> 8 ) & 0x7 ) 
 
606
                                                                {
 
607
                                                                case 1:
 
608
                                                                        pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
 
609
                                                                        break;
 
610
                                                                case 2:
 
611
                                                                        pSoftEvent->ulEventType = cOCT6100_TONE_STOP;
 
612
                                                                        break;
 
613
                                                                case 3:
 
614
                                                                        /* This one is a little tricky.  We first */
 
615
                                                                        /* generate the "PRESENT" event and then generate the "STOP" event. */
 
616
 
 
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;
 
624
 
 
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;
 
629
 
 
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) )
 
633
                                                                        {
 
634
                                                                                mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
 
635
                                                                                pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
 
636
 
 
637
                                                                                pSoftEvent->ulEventType = cOCT6100_TONE_STOP;
 
638
                                                                        }
 
639
                                                                        else
 
640
                                                                        {
 
641
                                                                                /* Set the overflow flag of the buffer. */
 
642
                                                                                pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
 
643
 
 
644
                                                                                /* We continue in the loop in order to empty the hardware buffer. */
 
645
                                                                                continue;
 
646
                                                                        }
 
647
                                                                        
 
648
                                                                        break;
 
649
                                                                case 4:
 
650
                                                                        pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
 
651
                                                                        break;
 
652
                                                                default:
 
653
                                                                        pSharedInfo->ErrorStats.ulToneDetectorErrorCnt++;
 
654
                                                                        /* do not process this packet*/
 
655
                                                                        continue;
 
656
                                                                }
 
657
 
 
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;
 
663
 
 
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;
 
668
 
 
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;
 
672
                                                        }
 
673
                                                        else
 
674
                                                        {
 
675
                                                                /* Set the overflow flag of the buffer. */
 
676
                                                                pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
 
677
 
 
678
                                                                /* We continue in the loop in order to empty the hardware buffer. */
 
679
                                                        }
 
680
                                                }
 
681
                                                else
 
682
                                                {
 
683
                                                        BOOL fSSTone;
 
684
 
 
685
                                                        ulResult = Oct6100ApiIsSSTone( 
 
686
                                                                                                                f_pApiInstance, 
 
687
                                                                                                                pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID, 
 
688
                                                                                                                &fSSTone );
 
689
                                                        if ( ulResult != cOCT6100_ERR_OK )
 
690
                                                                return ulResult;
 
691
 
 
692
                                                        if ( fSSTone == TRUE )
 
693
                                                        {
 
694
                                                                /* Check if this is a "PRESENT" or "STOP" event */
 
695
                                                                switch( ( ( ausReadData[ j ] >> 8 ) & 0x7 ) )
 
696
                                                                {
 
697
                                                                case 1:
 
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 );
 
701
                                                                        break;
 
702
                                                                case 2:
 
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;
 
706
                                                                        break;
 
707
                                                                default:
 
708
                                                                        break;
 
709
                                                                }
 
710
                                                        }
 
711
                                                }
 
712
                                        }
 
713
                                        ulToneCnt++;
 
714
 
 
715
                                        /* Check the other tone of this word. */
 
716
                                        if ( ( ausReadData[ j ] & 0x7 ) != 0x0 )
 
717
                                        {
 
718
                                                if ((( pEchoChannel->aulToneConf[ ulToneCnt / 32 ] >> ( 31 - ( ulToneCnt % 32 ))) & 0x1) == 1 )
 
719
                                                {
 
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) )
 
723
                                                        {
 
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;
 
727
 
 
728
                                                                /* Decode the event type. */
 
729
                                                                switch(( ausReadData[ j ] ) & 0x7 ) 
 
730
                                                                {
 
731
                                                                case 1:
 
732
                                                                        pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
 
733
                                                                        break;
 
734
                                                                case 2:
 
735
                                                                        pSoftEvent->ulEventType = cOCT6100_TONE_STOP;
 
736
                                                                        break;
 
737
                                                                case 3:
 
738
                                                                        /* This one is a little tricky.  We first */
 
739
                                                                        /* generate the "PRESENT" event and then generate the "STOP" event. */
 
740
 
 
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;
 
748
 
 
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;
 
753
 
 
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) )
 
757
                                                                        {
 
758
                                                                                mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
 
759
                                                                                pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
 
760
 
 
761
                                                                                pSoftEvent->ulEventType = cOCT6100_TONE_STOP;
 
762
                                                                        }
 
763
                                                                        else
 
764
                                                                        {
 
765
                                                                                /* Set the overflow flag of the buffer. */
 
766
                                                                                pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
 
767
 
 
768
                                                                                /* We continue in the loop in order to empty the hardware buffer. */
 
769
                                                                                continue;
 
770
                                                                        }
 
771
                                                                        
 
772
                                                                        break;
 
773
                                                                case 4:
 
774
                                                                        pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
 
775
                                                                        break;
 
776
                                                                default:
 
777
                                                                        pSharedInfo->ErrorStats.ulToneDetectorErrorCnt++;
 
778
                                                                        /* Do not process this packet. */
 
779
                                                                        continue;
 
780
                                                                }
 
781
 
 
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;
 
787
 
 
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;
 
792
 
 
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;
 
796
 
 
797
                                                        }
 
798
                                                        else
 
799
                                                        {
 
800
                                                                /* Set the overflow flag of the buffer. */
 
801
                                                                pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
 
802
 
 
803
                                                                /* We continue in the loop in order to empty the hardware buffer. */
 
804
                                                        }
 
805
                                                }
 
806
                                                else
 
807
                                                {
 
808
                                                        BOOL fSSTone;
 
809
 
 
810
                                                        ulResult = Oct6100ApiIsSSTone( 
 
811
                                                                                                                f_pApiInstance, 
 
812
                                                                                                                pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID, 
 
813
                                                                                                                &fSSTone );
 
814
                                                        if ( ulResult != cOCT6100_ERR_OK )
 
815
                                                                return ulResult;
 
816
 
 
817
                                                        if ( fSSTone == TRUE )
 
818
                                                        {
 
819
                                                                /* Check if this is a "PRESENT" event. */
 
820
                                                                switch ( ( ausReadData[ j ] ) & 0x7 ) 
 
821
                                                                {
 
822
                                                                case 1:
 
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 );
 
826
                                                                        break;
 
827
                                                                case 2:
 
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;
 
831
                                                                        break;
 
832
                                                                default:
 
833
                                                                        break;
 
834
                                                                }
 
835
                                                        }
 
836
                                                }
 
837
                                        }
 
838
                                        ulToneCnt++;
 
839
                                }
 
840
                        }
 
841
                        else
 
842
                        {
 
843
                                /* Set the overflow flag of the buffer. */
 
844
                                pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
 
845
 
 
846
                                /* We continue in the loop in order to empty the hardware buffer. */
 
847
                        }
 
848
 
 
849
                        /* Update the control variables of the buffer. */
 
850
                        ulChipReadPtr++;
 
851
                        if ( ulChipReadPtr == cOCT6100_NUM_PGSP_EVENT_OUT )
 
852
                                ulChipReadPtr = 0;
 
853
                }
 
854
        }
 
855
 
 
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 )
 
861
                return ulResult;
 
862
 
 
863
 
 
864
 
 
865
        return cOCT6100_ERR_OK;
 
866
}
 
867
#endif
 
868
 
 
869
 
 
870
 
 
871
 
 
872
 
 
873
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
874
 
 
875
Function:               Oct6100BufferPlayoutGetEventSer
 
876
 
 
877
Description:    Retreives an array of buffer playout event from the software 
 
878
                                event buffer.
 
879
 
 
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.
 
885
 
 
886
f_pEventGetPlayoutStop  Pointer to structure which will contain the retreived
 
887
                                                events.
 
888
 
 
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 )
 
894
{
 
895
        tPOCT6100_SHARED_INFO                           pSharedInfo;
 
896
        tPOCT6100_API_BUFFER_PLAYOUT_EVENT      pSoftEvent;
 
897
        UINT32  ulSoftReadPnt;
 
898
        UINT32  ulSoftWritePnt;
 
899
        UINT32  ulSoftBufSize;
 
900
        UINT32  ulNumEventsReturned;
 
901
        UINT32  ulResult;
 
902
 
 
903
        /* Get local pointer(s). */
 
904
        pSharedInfo = f_pApiInstance->pSharedInfo;
 
905
 
 
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;
 
910
        
 
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;
 
914
 
 
915
        /* Checking max playout events. */
 
916
        if ( f_pBufPlayoutGetEvent->ulMaxEvent > pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize )
 
917
                return cOCT6100_ERR_BUFFER_PLAYOUT_MAX_EVENT;
 
918
 
 
919
        if ( f_pBufPlayoutGetEvent->fResetBufs == FALSE )
 
920
        {
 
921
                /* Check if events need to be fetched from the chip. */
 
922
                ulSoftReadPnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr;
 
923
                ulSoftWritePnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr;
 
924
 
 
925
                if ( ulSoftReadPnt == ulSoftWritePnt )
 
926
                {
 
927
                        ulResult = Oct6100BufferPlayoutTransferEvents( f_pApiInstance, f_pBufPlayoutGetEvent->fResetBufs );
 
928
                        if ( ulResult != cOCT6100_ERR_OK )
 
929
                                return ulResult;
 
930
                }
 
931
 
 
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;
 
937
 
 
938
                if ( ulSoftReadPnt != ulSoftWritePnt )
 
939
                {
 
940
                        ulNumEventsReturned = 0;
 
941
 
 
942
                        while( (ulSoftReadPnt != ulSoftWritePnt) && ( ulNumEventsReturned != f_pBufPlayoutGetEvent->ulMaxEvent) )
 
943
                        {
 
944
                                /* Get a pointer to the first event in the buffer. */
 
945
                                mOCT6100_GET_BUFFER_PLAYOUT_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
 
946
                                pSoftEvent += ulSoftReadPnt;
 
947
                                
 
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;
 
954
                                
 
955
                                /* Update the pointers of the soft buffer. */
 
956
                                ulSoftReadPnt++;
 
957
                                if ( ulSoftReadPnt == ulSoftBufSize )
 
958
                                        ulSoftReadPnt = 0;
 
959
 
 
960
                                ulNumEventsReturned++;
 
961
                        }
 
962
 
 
963
                        pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr = ulSoftReadPnt;
 
964
 
 
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 ) */
 
969
                        {
 
970
                                f_pBufPlayoutGetEvent->fMoreEvents = FALSE;
 
971
                                
 
972
                                /* Remember this state in the interrupt manager. */
 
973
                                pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE;
 
974
                        }
 
975
 
 
976
                        f_pBufPlayoutGetEvent->ulNumValidEvent = ulNumEventsReturned;
 
977
                }
 
978
                else /* if ( ulSoftReadPnt == ulSoftWritePnt ) */
 
979
                {
 
980
                        /* No valid buffer playout events. */
 
981
                        f_pBufPlayoutGetEvent->ulNumValidEvent = 0;             
 
982
                        f_pBufPlayoutGetEvent->fMoreEvents = FALSE;
 
983
 
 
984
                        /* Remember this state in the interrupt manager. */
 
985
                        pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE;
 
986
                        
 
987
                        return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_BUF_EMPTY;
 
988
                }
 
989
        }
 
990
        else /* ( f_pEventGetPlayoutStop->fResetBufs == TRUE ) */
 
991
        {
 
992
                /* Check with the hardware first. */
 
993
                ulResult = Oct6100BufferPlayoutTransferEvents( f_pApiInstance, f_pBufPlayoutGetEvent->fResetBufs );
 
994
                if ( ulResult != cOCT6100_ERR_OK )
 
995
                        return ulResult;
 
996
 
 
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;
 
1000
 
 
1001
                f_pBufPlayoutGetEvent->fMoreEvents = FALSE;
 
1002
                f_pBufPlayoutGetEvent->ulNumValidEvent = 0;
 
1003
 
 
1004
                /* Remember this state in the interrupt manager. */
 
1005
                pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE;
 
1006
        }
 
1007
 
 
1008
        return cOCT6100_ERR_OK;
 
1009
}
 
1010
#endif
 
1011
 
 
1012
 
 
1013
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
1014
 
 
1015
Function:               Oct6100BufferPlayoutTransferEvents
 
1016
 
 
1017
Description:    Check all channels that are currently playing a buffer and 
 
1018
                                generate an event if a buffer has stopped playing.
 
1019
 
 
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.
 
1025
 
 
1026
f_ulResetBuf                    Reset flag.
 
1027
 
 
1028
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
1029
#if !SKIP_Oct6100BufferPlayoutTransferEvents
 
1030
UINT32 Oct6100BufferPlayoutTransferEvents(
 
1031
                                IN OUT  tPOCT6100_INSTANCE_API                  f_pApiInstance,
 
1032
                                IN              UINT32                                                  f_ulResetBuf )
 
1033
{
 
1034
        tPOCT6100_SHARED_INFO                           pSharedInfo;
 
1035
        tPOCT6100_API_CHANNEL                           pEchoChannel;
 
1036
 
 
1037
        UINT32  ulChannelIndex;
 
1038
        UINT32  ulResult;
 
1039
        UINT32  ulLastBufPlayoutEventBufferOverflowCnt;
 
1040
 
 
1041
        /* Get local pointer(s). */
 
1042
        pSharedInfo = f_pApiInstance->pSharedInfo;
 
1043
 
 
1044
        /* If the buffer is to be reset then clear the overflow flag. */
 
1045
        if ( f_ulResetBuf == TRUE )
 
1046
        {
 
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;
 
1051
        }
 
1052
 
 
1053
        /* Check if buffer playout has been activated on some ports. */
 
1054
        if ( pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts == 0 )
 
1055
        {
 
1056
                /* Buffer playout has not been activated on any channel, */
 
1057
                /* let's not waste time here. */
 
1058
                return cOCT6100_ERR_OK;
 
1059
        }
 
1060
 
 
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;
 
1063
 
 
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++ )
 
1066
        {
 
1067
                mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, ulChannelIndex );
 
1068
                
 
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 )
 
1074
                {
 
1075
                        /* Read in the event only if there's enough room in the soft buffer. */
 
1076
                        if ( ulLastBufPlayoutEventBufferOverflowCnt == pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt )
 
1077
                        {
 
1078
                                /* Check Rout buffer playout first. */
 
1079
                                if ( ( pEchoChannel->fRinBufPlayoutNotifyOnStop == TRUE )
 
1080
                                        && ( pEchoChannel->fRinBufPlaying == TRUE ) )
 
1081
                                {
 
1082
                                        ulResult = Oct6100BufferPlayoutCheckForSpecificEvent( f_pApiInstance, ulChannelIndex, cOCT6100_CHANNEL_PORT_ROUT, TRUE, NULL );
 
1083
                                        if ( ulResult != cOCT6100_ERR_OK )
 
1084
                                                return ulResult;
 
1085
                                }
 
1086
                        }
 
1087
                        else /* if ( ulLastBufPlayoutEventBufferOverflowCnt != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt ) */
 
1088
                        {
 
1089
                                /* Get out of the loop, no more events can be inserted in the soft buffer. */
 
1090
                                break;
 
1091
                        }
 
1092
 
 
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 )
 
1096
                        {
 
1097
                                /* Check Sout buffer playout. */
 
1098
                                if ( ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == TRUE )
 
1099
                                        && ( pEchoChannel->fSoutBufPlaying == TRUE ) )
 
1100
                                {
 
1101
                                        ulResult = Oct6100BufferPlayoutCheckForSpecificEvent( f_pApiInstance, ulChannelIndex, cOCT6100_CHANNEL_PORT_SOUT, TRUE, NULL );
 
1102
                                        if ( ulResult != cOCT6100_ERR_OK )
 
1103
                                                return ulResult;
 
1104
                                }
 
1105
                        }
 
1106
                        else /* if ( ulLastBufPlayoutEventBufferOverflowCnt != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt ) */
 
1107
                        {
 
1108
                                /* Get out of the loop, no more events can be inserted in the soft buffer. */
 
1109
                                break;
 
1110
                        }
 
1111
                }
 
1112
        }
 
1113
 
 
1114
        return cOCT6100_ERR_OK;
 
1115
}
 
1116
#endif
 
1117
 
 
1118
 
 
1119
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
1120
 
 
1121
Function:               Oct6100BufferPlayoutCheckForSpecificEvent
 
1122
 
 
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.
 
1126
 
 
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.
 
1132
 
 
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.
 
1137
 
 
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 )
 
1146
{
 
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;
 
1152
 
 
1153
        UINT32  ulResult;
 
1154
        UINT16  usReadData;
 
1155
        UINT32  ulReadPtrBytesOfst;
 
1156
        UINT32  ulReadPtrBitOfst;
 
1157
        UINT32  ulReadPtrFieldSize;
 
1158
 
 
1159
        UINT32  ulWritePtrBytesOfst;
 
1160
        UINT32  ulWritePtrBitOfst;
 
1161
        UINT32  ulWritePtrFieldSize;
 
1162
 
 
1163
        UINT32  ulPlayoutBaseAddress;
 
1164
        UINT32  ulTempData;
 
1165
        UINT32  ulReadPtr;
 
1166
        UINT32  ulMask;
 
1167
        UINT32  ulWritePtr;
 
1168
        UINT32  ulUserEventId;
 
1169
        UINT32  ulEventType;
 
1170
 
 
1171
        /* Get local pointer(s). */
 
1172
        pSharedInfo = f_pApiInstance->pSharedInfo;
 
1173
 
 
1174
        /* Compare the read and write pointers for matching.  If they matched, playout stopped. */
 
1175
        mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, f_ulChannelIndex );
 
1176
 
 
1177
        /* Set the playout feature base address. */
 
1178
        ulPlayoutBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_ulChannelIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst;
 
1179
 
 
1180
        if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_ROUT )
 
1181
        {
 
1182
                /* Check on the Rout port. */
 
1183
                ulUserEventId = pEchoChannel->ulRinUserBufPlayoutEventId;
 
1184
                ulEventType = pEchoChannel->byRinPlayoutStopEventType;
 
1185
 
 
1186
                ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.usDwordOffset * 4;
 
1187
                ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byBitOffset;
 
1188
                ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byFieldSize;
 
1189
 
 
1190
                ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.usDwordOffset * 4;
 
1191
                ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byBitOffset;
 
1192
                ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byFieldSize;
 
1193
        }
 
1194
        else /* if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_SOUT ) */
 
1195
        {
 
1196
                /* Check on the Sout port. */
 
1197
                ulUserEventId = pEchoChannel->ulSoutUserBufPlayoutEventId;
 
1198
                ulEventType = pEchoChannel->bySoutPlayoutStopEventType;
 
1199
 
 
1200
                ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.usDwordOffset * 4;
 
1201
                ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byBitOffset;
 
1202
                ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byFieldSize;
 
1203
 
 
1204
                ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.usDwordOffset * 4;
 
1205
                ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byBitOffset;
 
1206
                ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byFieldSize;
 
1207
        }
 
1208
 
 
1209
        /* Retrieve the current write pointer. */
 
1210
        mOCT6100_RETRIEVE_NLP_CONF_DWORD(       f_pApiInstance, 
 
1211
                                                                                pEchoChannel, 
 
1212
                                                                                ulPlayoutBaseAddress + ulWritePtrBytesOfst, 
 
1213
                                                                                &ulTempData,
 
1214
                                                                                ulResult );
 
1215
        if ( ulResult != cOCT6100_ERR_OK )
 
1216
                return ulResult;
 
1217
 
 
1218
        mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask );
 
1219
 
 
1220
        /* Store the write pointer.*/
 
1221
        ulWritePtr = ( ulTempData & ulMask ) >> ulWritePtrBitOfst;
 
1222
 
 
1223
        /* Read the read pointer.*/
 
1224
        ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
 
1225
 
 
1226
        ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
 
1227
        ReadParams.pusReadData = &usReadData;
 
1228
        ReadParams.ulReadAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst;
 
1229
 
 
1230
        /* Optimize this access by only reading the word we are interested in. */
 
1231
        if ( ulReadPtrBitOfst < 16 )
 
1232
                ReadParams.ulReadAddress += 2;
 
1233
 
 
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 )
 
1237
                return ulResult;
 
1238
 
 
1239
        /* Move data at correct position according to what was read. */
 
1240
        if ( ulReadPtrBitOfst < 16 )
 
1241
                ulTempData = usReadData;
 
1242
        else
 
1243
                ulTempData = usReadData << 16;
 
1244
        
 
1245
        mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask );
 
1246
        
 
1247
        /* Store the read pointer. */
 
1248
        ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst;
 
1249
 
 
1250
        /* Playout has finished when the read pointer reaches the write pointer. */
 
1251
        if ( ulReadPtr != ulWritePtr )
 
1252
        {
 
1253
                /* Still playing -- do not generate an event. */
 
1254
                if ( f_pfEventDetected != NULL )
 
1255
                        *f_pfEventDetected = FALSE;
 
1256
        }
 
1257
        else
 
1258
        {
 
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 ) )
 
1263
                {
 
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;
 
1267
 
 
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;
 
1274
                        
 
1275
                        /* Generate millisecond timestamp. */
 
1276
                        GetTimeParms.pProcessContext = f_pApiInstance->pProcessContext;
 
1277
                        ulResult = Oct6100UserGetTime( &GetTimeParms );
 
1278
                        if ( ulResult != cOCT6100_ERR_OK )
 
1279
                                return ulResult;
 
1280
 
 
1281
                        pSoftEvent->ulTimestamp = ( GetTimeParms.aulWallTimeUs[ 0 ] / 1000 );
 
1282
                        pSoftEvent->ulTimestamp += ( GetTimeParms.aulWallTimeUs[ 1 ] ) * ( 0xFFFFFFFF / 1000 );
 
1283
 
 
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;
 
1288
 
 
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;
 
1292
                }
 
1293
                else if ( f_fSaveToSoftBuffer == TRUE ) 
 
1294
                {
 
1295
                        /* Set the overflow flag of the buffer. */
 
1296
                        pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt++;
 
1297
                }
 
1298
 
 
1299
                /* Update the channel entry to set the playing flag to FALSE. */
 
1300
 
 
1301
                /* Select the port of interest. */
 
1302
                if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_ROUT )
 
1303
                {
 
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--;
 
1307
 
 
1308
                        pEchoChannel->fRinBufPlaying = FALSE;
 
1309
                        pEchoChannel->fRinBufPlayoutNotifyOnStop = FALSE;
 
1310
 
 
1311
                        /* Clear optimization flag if possible. */
 
1312
                        if ( ( pEchoChannel->fSoutBufPlaying == FALSE )
 
1313
                                && ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == FALSE ) )
 
1314
                        {
 
1315
                                /* Buffer playout is no more active on this channel. */
 
1316
                                pEchoChannel->fBufPlayoutActive = FALSE;
 
1317
                        }
 
1318
                }
 
1319
                else /* f_ulChannelPort == cOCT6100_CHANNEL_PORT_SOUT */
 
1320
                {
 
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--;
 
1324
 
 
1325
                        pEchoChannel->fSoutBufPlaying = FALSE;
 
1326
                        pEchoChannel->fSoutBufPlayoutNotifyOnStop = FALSE;
 
1327
 
 
1328
                        /* Clear optimization flag if possible. */
 
1329
                        if ( ( pEchoChannel->fRinBufPlaying == FALSE )
 
1330
                                && ( pEchoChannel->fRinBufPlayoutNotifyOnStop == FALSE ) )
 
1331
                        {
 
1332
                                /* Buffer playout is no more active on this channel. */
 
1333
                                pEchoChannel->fBufPlayoutActive = FALSE;
 
1334
                        }
 
1335
                }
 
1336
 
 
1337
                /* Return that an event was detected. */
 
1338
                if ( f_pfEventDetected != NULL )
 
1339
                        *f_pfEventDetected = TRUE;
 
1340
        }
 
1341
        
 
1342
        return cOCT6100_ERR_OK;
 
1343
}
 
1344
#endif
 
1345
 
 
1346
#endif /* cOCT6100_REMOVE_EVENTS */