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

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Tzafrir Cohen
  • Date: 2008-08-28 22:58:23 UTC
  • mfrom: (11.1.11 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080828225823-r8bdunirm8hmc76m
Tags: 1:1.4.11~dfsg-2
* Patch xpp_fxs_power: Fixed an issue with hook detection of the Astribank
  FXS module.
* Don't fail init.d script if fxotune fails. This may happen if running it
  when Asterisk is already running.
* Bump standards version to 3.8.0.0 .
* Ignore false lintian warning ("m-a a-i" has "a a").
* Patch xpp_fxo_cid_always: do always pass PCM if that's what the user
  asked.
* Patch vzaphfc_proc_root_dir: fix vzaphfc on 2.6.26.
* Patch wcte12xp_flags: Proper time for irq save flags.
* Patch headers_2627: Fix location of semaphore.h for 2.6.27 .
* Patch xpp_fxs_dtmf_leak: Don't play DTMFs to the wrong channel.
* Patch wctdm_fix_alarm: Fix sending channel alarms.
* Patch device_class_2626: Fix building 2.6.26 (Closes: #493397).
* Using dh_lintian for lintian overrides, hence requiring debhelper 6.0.7.
* Lintian: we know we have direct changes. Too bad we're half-upstream :-(
* Fix doc-base section names. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
2
 
 
3
File: oct6100_events.c
 
4
 
 
5
    Copyright (c) 2001-2007 Octasic Inc.
 
6
    
 
7
Description: 
 
8
 
 
9
        This file contains functions used to retrieve tone and playout events.
 
10
 
 
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.
 
15
 
 
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 
 
19
for more details. 
 
20
 
 
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.
 
24
 
 
25
$Octasic_Release: OCT612xAPI-01.00-PR49 $
 
26
 
 
27
$Octasic_Revision: 81 $
 
28
 
 
29
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
30
 
 
31
 
 
32
/*****************************  INCLUDE FILES  *******************************/
 
33
 
 
34
#include "octdef.h"
 
35
 
 
36
#include "oct6100api/oct6100_defines.h"
 
37
#include "oct6100api/oct6100_errors.h"
 
38
#include "oct6100api/oct6100_apiud.h"
 
39
 
 
40
#include "apilib/octapi_llman.h"
 
41
 
 
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"
 
53
 
 
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"
 
60
 
 
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"
 
67
 
 
68
/****************************  PUBLIC FUNCTIONS  *****************************/
 
69
 
 
70
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
71
 
 
72
Function:               Oct6100EventGetTone
 
73
 
 
74
Description:    Retreives an array of tone events.
 
75
 
 
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.
 
81
 
 
82
f_pEventGetTone                 Pointer to structure used to store the Tone events.                                             
 
83
 
 
84
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
85
#if !SKIP_Oct6100EventGetToneDef
 
86
UINT32 Oct6100EventGetToneDef(
 
87
                                tPOCT6100_EVENT_GET_TONE                f_pEventGetTone )
 
88
{
 
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;
 
94
 
 
95
        return cOCT6100_ERR_OK; 
 
96
}
 
97
#endif
 
98
 
 
99
 
 
100
#if !SKIP_Oct6100EventGetTone
 
101
UINT32 Oct6100EventGetTone(
 
102
                                tPOCT6100_INSTANCE_API                  f_pApiInstance,
 
103
                                tPOCT6100_EVENT_GET_TONE                f_pEventGetTone )
 
104
{
 
105
        tOCT6100_SEIZE_SERIALIZE_OBJECT         SeizeSerObj;
 
106
        tOCT6100_RELEASE_SERIALIZE_OBJECT       ReleaseSerObj;
 
107
        UINT32                                                          ulSerRes = cOCT6100_ERR_OK;
 
108
        UINT32                                                          ulFncRes = cOCT6100_ERR_OK;
 
109
 
 
110
        /* Set the process context of the serialize structure. */
 
111
        SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
112
        ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
113
 
 
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 )
 
119
        {
 
120
                /* Call the serialized function. */
 
121
                ulFncRes = Oct6100EventGetToneSer( f_pApiInstance, f_pEventGetTone );
 
122
        }
 
123
        else
 
124
        {
 
125
                return ulSerRes;
 
126
        }
 
127
 
 
128
        /* Release the seized semaphores. */
 
129
        ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
130
        ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj );
 
131
 
 
132
        /* If an error occured then return the error code. */
 
133
        if ( ulSerRes != cOCT6100_ERR_OK )
 
134
                return ulSerRes;
 
135
        if ( ulFncRes != cOCT6100_ERR_OK )
 
136
                return ulFncRes;
 
137
 
 
138
        return cOCT6100_ERR_OK;
 
139
}
 
140
#endif
 
141
 
 
142
 
 
143
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
144
 
 
145
Function:               Oct6100BufferPlayoutGetEvent
 
146
 
 
147
Description:    Retrieves an array of playout stop events.
 
148
 
 
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.
 
154
 
 
155
f_pBufPlayoutGetEvent   Pointer to structure used to store the playout events.
 
156
 
 
157
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
158
#if !SKIP_Oct6100BufferPlayoutGetEventDef
 
159
UINT32 Oct6100BufferPlayoutGetEventDef(
 
160
                                tPOCT6100_BUFFER_PLAYOUT_GET_EVENT      f_pBufPlayoutGetEvent )
 
161
{
 
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;
 
167
 
 
168
        return cOCT6100_ERR_OK; 
 
169
}
 
170
#endif
 
171
 
 
172
 
 
173
#if !SKIP_Oct6100BufferPlayoutGetEvent
 
174
UINT32 Oct6100BufferPlayoutGetEvent(
 
175
                                tPOCT6100_INSTANCE_API                                  f_pApiInstance,
 
176
                                tPOCT6100_BUFFER_PLAYOUT_GET_EVENT              f_pBufPlayoutGetEvent )
 
177
{
 
178
        tOCT6100_SEIZE_SERIALIZE_OBJECT         SeizeSerObj;
 
179
        tOCT6100_RELEASE_SERIALIZE_OBJECT       ReleaseSerObj;
 
180
        UINT32                                                          ulSerRes = cOCT6100_ERR_OK;
 
181
        UINT32                                                          ulFncRes = cOCT6100_ERR_OK;
 
182
 
 
183
        /* Set the process context of the serialize structure. */
 
184
        SeizeSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
185
        ReleaseSerObj.pProcessContext = f_pApiInstance->pProcessContext;
 
186
 
 
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 )
 
192
        {
 
193
                /* Call the serialized function. */
 
194
                ulFncRes = Oct6100BufferPlayoutGetEventSer( f_pApiInstance, f_pBufPlayoutGetEvent );
 
195
        }
 
196
        else
 
197
        {
 
198
                return ulSerRes;
 
199
        }
 
200
 
 
201
        /* Release the seized semaphores. */
 
202
        ReleaseSerObj.ulSerialObjHndl = f_pApiInstance->ulApiSerObj;
 
203
        ulSerRes = Oct6100UserReleaseSerializeObject( &ReleaseSerObj );
 
204
 
 
205
        /* If an error occured then return the error code. */
 
206
        if ( ulSerRes != cOCT6100_ERR_OK )
 
207
                return ulSerRes;
 
208
        if ( ulFncRes != cOCT6100_ERR_OK )
 
209
                return ulFncRes;
 
210
 
 
211
        return cOCT6100_ERR_OK;
 
212
}
 
213
#endif
 
214
 
 
215
 
 
216
/****************************  PRIVATE FUNCTIONS  ****************************/
 
217
 
 
218
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
219
 
 
220
Function:               Oct6100ApiGetEventsSwSizes
 
221
 
 
222
Description:    Gets the sizes of all portions of the API instance pertinent
 
223
                                to the management of the tone events and playout events
 
224
                                software buffers.
 
225
 
 
226
-------------------------------------------------------------------------------
 
227
|       Argument                |       Description
 
228
-------------------------------------------------------------------------------
 
229
f_pOpenChip                             Pointer to chip configuration struct.
 
230
f_pInstSizes                    Pointer to struct containing instance sizes.
 
231
 
 
232
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
233
#if !SKIP_Oct6100ApiGetEventsSwSizes
 
234
UINT32 Oct6100ApiGetEventsSwSizes(
 
235
                                IN              tPOCT6100_CHIP_OPEN                             f_pOpenChip,
 
236
                                OUT             tPOCT6100_API_INSTANCE_SIZES    f_pInstSizes )
 
237
{
 
238
 
 
239
        {
 
240
                UINT32  ulTempVar;
 
241
                
 
242
                /* Memory needed by soft tone event buffers. */
 
243
 
 
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 );
 
246
 
 
247
                /* Round off the sizes of the soft buffers above. */
 
248
                mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulSoftToneEventsBuffer, ulTempVar )
 
249
        }
 
250
 
 
251
        {
 
252
                UINT32  ulTempVar;
 
253
 
 
254
                /* Memory needed by soft playout stop event buffers. */
 
255
                if ( f_pOpenChip->ulSoftBufferPlayoutEventsBufSize != cOCT6100_INVALID_VALUE )
 
256
                {
 
257
                        f_pInstSizes->ulSoftBufPlayoutEventsBuffer = ( f_pOpenChip->ulSoftBufferPlayoutEventsBufSize + 1 ) * sizeof( tOCT6100_API_BUFFER_PLAYOUT_EVENT );
 
258
 
 
259
                        /* Round off the sizes of the soft buffers above. */
 
260
                        mOCT6100_ROUND_MEMORY_SIZE( f_pInstSizes->ulSoftBufPlayoutEventsBuffer, ulTempVar )
 
261
                }
 
262
                else /* if ( f_pInstSizes->ulSoftBufferPlayoutEventsBufSize == cOCT6100_INVALID_VALUE ) */
 
263
                {
 
264
                        f_pInstSizes->ulSoftBufPlayoutEventsBuffer = 0;
 
265
                }
 
266
        }
 
267
 
 
268
        return cOCT6100_ERR_OK;
 
269
}
 
270
#endif
 
271
 
 
272
 
 
273
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
274
 
 
275
Function:               Oct6100EventGetToneSer
 
276
 
 
277
Description:    Retreives an array of tone event from the software event buffer.
 
278
 
 
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.
 
284
 
 
285
f_pEventGetTone                 Pointer to structure which will contain the retreived
 
286
                                                events.
 
287
 
 
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 )
 
293
{
 
294
        tPOCT6100_SHARED_INFO           pSharedInfo;
 
295
        tPOCT6100_API_TONE_EVENT        pSoftEvent;
 
296
        UINT32  ulSoftReadPnt;
 
297
        UINT32  ulSoftWritePnt;
 
298
        UINT32  ulSoftBufSize;
 
299
        UINT32  ulNumEventsReturned;
 
300
        UINT32  ulResult;
 
301
 
 
302
        /* Get local pointer(s). */
 
303
        pSharedInfo = f_pApiInstance->pSharedInfo;
 
304
 
 
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;
 
309
        
 
310
        /* Check max tones. */
 
311
        if ( f_pEventGetTone->ulMaxToneEvent > pSharedInfo->ChipConfig.ulSoftToneEventsBufSize )
 
312
                return cOCT6100_ERR_EVENTS_MAX_TONES;
 
313
 
 
314
        if ( f_pEventGetTone->fResetBufs == FALSE )
 
315
        {
 
316
                /* Check if the events need to be fetched from the chip buffer. */
 
317
                ulSoftReadPnt = pSharedInfo->SoftBufs.ulToneEventBufferReadPtr;
 
318
                ulSoftWritePnt = pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
 
319
 
 
320
                if ( ulSoftReadPnt == ulSoftWritePnt )
 
321
                {
 
322
                        ulResult = Oct6100ApiTransferToneEvents( f_pApiInstance, f_pEventGetTone->fResetBufs );
 
323
                        if ( ulResult != cOCT6100_ERR_OK )
 
324
                                return ulResult;
 
325
                }
 
326
 
 
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;
 
332
 
 
333
                if ( ulSoftReadPnt != ulSoftWritePnt )
 
334
                {
 
335
                        ulNumEventsReturned = 0;
 
336
 
 
337
                        while( (ulSoftReadPnt != ulSoftWritePnt) && ( ulNumEventsReturned != f_pEventGetTone->ulMaxToneEvent) )
 
338
                        {
 
339
                                /* Get a pointer to the first event in the buffer. */
 
340
                                mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
 
341
                                pSoftEvent += ulSoftReadPnt;
 
342
                                
 
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;
 
349
 
 
350
                                /* Update the pointers of the soft buffer. */
 
351
                                ulSoftReadPnt++;
 
352
                                if ( ulSoftReadPnt == ulSoftBufSize )
 
353
                                        ulSoftReadPnt = 0;
 
354
 
 
355
                                ulNumEventsReturned++;
 
356
                        }
 
357
 
 
358
                        pSharedInfo->SoftBufs.ulToneEventBufferReadPtr = ulSoftReadPnt;
 
359
 
 
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 ) */
 
364
                        {
 
365
                                f_pEventGetTone->fMoreEvents = FALSE;
 
366
                                
 
367
                                /* Remember this state in the interrupt manager. */
 
368
                                pSharedInfo->IntrptManage.fToneEventsPending = FALSE;
 
369
                        }
 
370
 
 
371
                        f_pEventGetTone->ulNumValidToneEvent = ulNumEventsReturned;
 
372
                }
 
373
                else
 
374
                {
 
375
                        /* No valid tone.*/
 
376
                        f_pEventGetTone->ulNumValidToneEvent = 0;
 
377
                        f_pEventGetTone->fMoreEvents = FALSE;
 
378
 
 
379
                        /* Remember this state in the interrupt manager. */
 
380
                        pSharedInfo->IntrptManage.fToneEventsPending = FALSE;
 
381
                        
 
382
                        return cOCT6100_ERR_EVENTS_TONE_BUF_EMPTY;
 
383
                }
 
384
        }
 
385
        else /* ( f_pEventGetTone->fResetBufs == TRUE ) */
 
386
        {
 
387
                /* Empty the hardware buffer. */
 
388
                ulResult = Oct6100ApiTransferToneEvents( f_pApiInstance, f_pEventGetTone->fResetBufs );
 
389
                if ( ulResult != cOCT6100_ERR_OK )
 
390
                        return ulResult;
 
391
 
 
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;
 
395
 
 
396
                f_pEventGetTone->fMoreEvents = FALSE;
 
397
                f_pEventGetTone->ulNumValidToneEvent = 0;
 
398
 
 
399
                /* Remember this state in the interrupt manager. */
 
400
                pSharedInfo->IntrptManage.fToneEventsPending = FALSE;
 
401
        }
 
402
 
 
403
        return cOCT6100_ERR_OK;
 
404
}
 
405
#endif
 
406
 
 
407
 
 
408
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
409
 
 
410
Function:               Oct6100ApiTransferToneEvents
 
411
 
 
412
Description:    Transfers all tone events from the PGSP event out chip buffer 
 
413
                                to the soft buffer.
 
414
 
 
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.
 
420
 
 
421
f_ulResetBuf                    Reset flag.
 
422
 
 
423
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
424
#if !SKIP_Oct6100ApiTransferToneEvents
 
425
UINT32 Oct6100ApiTransferToneEvents(
 
426
                                IN OUT  tPOCT6100_INSTANCE_API                  f_pApiInstance,
 
427
                                IN              UINT32                                                  f_ulResetBuf )
 
428
{
 
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;
 
438
        
 
439
        UINT32  usChannelIndex;
 
440
        UINT32  ulBaseTimestamp;
 
441
        UINT32  ulToneCnt;
 
442
        UINT32  ulNumWordsToRead;
 
443
        UINT32  ulEventCode;
 
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
                                        ulEventCode = ( ausReadData[ j ] >> 8 ) & 0x7;
 
592
 
 
593
                                        if ( ulEventCode != 0x0 )
 
594
                                        {
 
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 )
 
597
                                                {
 
598
                                                        BOOL f2100Tone;
 
599
                                                        
 
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,
 
603
                                                                                                                        &f2100Tone);
 
604
                                                        if ( ulResult != cOCT6100_ERR_OK )
 
605
                                                                return ulResult;
 
606
                                                        
 
607
                                                        if (  (f2100Tone == FALSE) ||
 
608
                                                                ( (f2100Tone == TRUE) && (ulEventCode != 2) ) ||
 
609
                                                                ( (f2100Tone == TRUE) && pSharedInfo->ChipConfig.fEnable2100StopEvent == TRUE ) )
 
610
                                                        {
 
611
                                                
 
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) )
 
615
                                                                {
 
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;
 
619
 
 
620
                                                                        /* Decode the event type. */
 
621
                                                                        switch( ulEventCode ) 
 
622
                                                                        {
 
623
                                                                        case 1:
 
624
                                                                                pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
 
625
                                                                                break;
 
626
                                                                        case 2:
 
627
                                                                                pSoftEvent->ulEventType = cOCT6100_TONE_STOP;
 
628
                                                                                break;
 
629
                                                                        case 3:
 
630
                                                                                /* This one is a little tricky.  We first */
 
631
                                                                                /* generate the "PRESENT" event and then generate the "STOP" event. */
 
632
 
 
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;
 
640
 
 
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;
 
645
 
 
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) )
 
649
                                                                                {
 
650
                                                                                        mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
 
651
                                                                                        pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
 
652
 
 
653
                                                                                        pSoftEvent->ulEventType = cOCT6100_TONE_STOP;
 
654
                                                                                }
 
655
                                                                                else
 
656
                                                                                {
 
657
                                                                                        /* Set the overflow flag of the buffer. */
 
658
                                                                                        pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
 
659
 
 
660
                                                                                        /* We continue in the loop in order to empty the hardware buffer. */
 
661
                                                                                        continue;
 
662
                                                                                }
 
663
                                                                                
 
664
                                                                                break;
 
665
                                                                        case 4:
 
666
                                                                                pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
 
667
                                                                                break;
 
668
                                                                        default:
 
669
                                                                                pSharedInfo->ErrorStats.ulToneDetectorErrorCnt++;
 
670
                                                                                /* do not process this packet*/
 
671
                                                                                continue;
 
672
                                                                        }
 
673
 
 
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;
 
679
 
 
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;
 
684
 
 
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;
 
688
                                                                }
 
689
                                                                else
 
690
                                                                {
 
691
                                                                        /* Set the overflow flag of the buffer. */
 
692
                                                                        pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
 
693
 
 
694
                                                                        /* We continue in the loop in order to empty the hardware buffer. */
 
695
                                                                }
 
696
                                                        }
 
697
                                                }
 
698
                                                else
 
699
                                                {
 
700
                                                        BOOL fSSTone;
 
701
 
 
702
                                                        ulResult = Oct6100ApiIsSSTone( 
 
703
                                                                                                                f_pApiInstance, 
 
704
                                                                                                                pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID, 
 
705
                                                                                                                &fSSTone );
 
706
                                                        if ( ulResult != cOCT6100_ERR_OK )
 
707
                                                                return ulResult;
 
708
 
 
709
                                                        if ( fSSTone == TRUE )
 
710
                                                        {
 
711
                                                                /* Check if this is a "PRESENT" or "STOP" event */
 
712
                                                                switch( ulEventCode )
 
713
                                                                {
 
714
                                                                case 1:
 
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 );
 
718
                                                                        break;
 
719
                                                                case 2:
 
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;
 
723
                                                                        break;
 
724
                                                                default:
 
725
                                                                        break;
 
726
                                                                }
 
727
                                                        }
 
728
                                                }
 
729
                                        }
 
730
                                        ulToneCnt++;
 
731
                
 
732
                                        /* Check the other tone of this word. */
 
733
                                        ulEventCode = ausReadData[ j ] & 0x7;
 
734
                                        
 
735
                                        if ( ulEventCode != 0x0 )
 
736
                                        {
 
737
                                                if ((( pEchoChannel->aulToneConf[ ulToneCnt / 32 ] >> ( 31 - ( ulToneCnt % 32 ))) & 0x1) == 1 )
 
738
                                                {
 
739
                                                        BOOL f2100Tone;
 
740
                                                        
 
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,
 
744
                                                                                                                        &f2100Tone);
 
745
                                                        if ( ulResult != cOCT6100_ERR_OK )
 
746
                                                                return ulResult;
 
747
                                                        
 
748
                                                        if (  (f2100Tone == FALSE) ||
 
749
                                                                ( (f2100Tone == TRUE) && (ulEventCode != 2) ) ||
 
750
                                                                ( (f2100Tone == TRUE) && pSharedInfo->ChipConfig.fEnable2100StopEvent == TRUE ) )
 
751
                                                        {
 
752
                                                        
 
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) )
 
756
                                                                {
 
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;
 
760
 
 
761
                                                                        /* Decode the event type. */
 
762
                                                                        switch( ulEventCode ) 
 
763
                                                                        {
 
764
                                                                        case 1:
 
765
                                                                                pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
 
766
                                                                                break;
 
767
                                                                        case 2:
 
768
                                                                                pSoftEvent->ulEventType = cOCT6100_TONE_STOP;
 
769
                                                                                break;
 
770
                                                                        case 3:
 
771
                                                                                /* This one is a little tricky.  We first */
 
772
                                                                                /* generate the "PRESENT" event and then generate the "STOP" event. */
 
773
 
 
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;
 
781
 
 
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;
 
786
 
 
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) )
 
790
                                                                                {
 
791
                                                                                        mOCT6100_GET_TONE_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
 
792
                                                                                        pSoftEvent += pSharedInfo->SoftBufs.ulToneEventBufferWritePtr;
 
793
 
 
794
                                                                                        pSoftEvent->ulEventType = cOCT6100_TONE_STOP;
 
795
                                                                                }
 
796
                                                                                else
 
797
                                                                                {
 
798
                                                                                        /* Set the overflow flag of the buffer. */
 
799
                                                                                        pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
 
800
 
 
801
                                                                                        /* We continue in the loop in order to empty the hardware buffer. */
 
802
                                                                                        continue;
 
803
                                                                                }
 
804
                                                                                
 
805
                                                                                break;
 
806
                                                                        case 4:
 
807
                                                                                pSoftEvent->ulEventType = cOCT6100_TONE_PRESENT;
 
808
                                                                                break;
 
809
                                                                        default:
 
810
                                                                                pSharedInfo->ErrorStats.ulToneDetectorErrorCnt++;
 
811
                                                                                /* Do not process this packet. */
 
812
                                                                                continue;
 
813
                                                                        }
 
814
 
 
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;
 
820
 
 
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;
 
825
 
 
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;
 
829
 
 
830
                                                                }
 
831
                                                                else
 
832
                                                                {
 
833
                                                                        /* Set the overflow flag of the buffer. */
 
834
                                                                        pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
 
835
 
 
836
                                                                        /* We continue in the loop in order to empty the hardware buffer. */
 
837
                                                                }
 
838
                                                        }
 
839
                                                }
 
840
                                                else
 
841
                                                {
 
842
                                                        BOOL fSSTone;
 
843
 
 
844
                                                        ulResult = Oct6100ApiIsSSTone( 
 
845
                                                                                                                f_pApiInstance, 
 
846
                                                                                                                pSharedInfo->ImageInfo.aToneInfo[ ulToneCnt ].ulToneID, 
 
847
                                                                                                                &fSSTone );
 
848
                                                        if ( ulResult != cOCT6100_ERR_OK )
 
849
                                                                return ulResult;
 
850
 
 
851
                                                        if ( fSSTone == TRUE )
 
852
                                                        {
 
853
                                                                /* Check if this is a "PRESENT" event. */
 
854
                                                                switch ( ulEventCode ) 
 
855
                                                                {
 
856
                                                                case 1:
 
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 );
 
860
                                                                        break;
 
861
                                                                case 2:
 
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;
 
865
                                                                        break;
 
866
                                                                default:
 
867
                                                                        break;
 
868
                                                                }
 
869
                                                        }
 
870
                                                }
 
871
                                        }
 
872
                                        ulToneCnt++;
 
873
                                }
 
874
                        }
 
875
                        else
 
876
                        {
 
877
                                /* Set the overflow flag of the buffer. */
 
878
                                pSharedInfo->SoftBufs.ulToneEventBufferOverflowCnt++;
 
879
 
 
880
                                /* We continue in the loop in order to empty the hardware buffer. */
 
881
                        }
 
882
 
 
883
                        /* Update the control variables of the buffer. */
 
884
                        ulChipReadPtr++;
 
885
                        if ( ulChipReadPtr == cOCT6100_NUM_PGSP_EVENT_OUT )
 
886
                                ulChipReadPtr = 0;
 
887
                }
 
888
        }
 
889
 
 
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 )
 
895
                return ulResult;
 
896
 
 
897
 
 
898
 
 
899
        return cOCT6100_ERR_OK;
 
900
}
 
901
#endif
 
902
 
 
903
 
 
904
 
 
905
 
 
906
 
 
907
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
908
 
 
909
Function:               Oct6100BufferPlayoutGetEventSer
 
910
 
 
911
Description:    Retreives an array of buffer playout event from the software 
 
912
                                event buffer.
 
913
 
 
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.
 
919
 
 
920
f_pEventGetPlayoutStop  Pointer to structure which will contain the retreived
 
921
                                                events.
 
922
 
 
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 )
 
928
{
 
929
        tPOCT6100_SHARED_INFO                           pSharedInfo;
 
930
        tPOCT6100_API_BUFFER_PLAYOUT_EVENT      pSoftEvent;
 
931
        UINT32  ulSoftReadPnt;
 
932
        UINT32  ulSoftWritePnt;
 
933
        UINT32  ulSoftBufSize;
 
934
        UINT32  ulNumEventsReturned;
 
935
        UINT32  ulResult;
 
936
 
 
937
        /* Get local pointer(s). */
 
938
        pSharedInfo = f_pApiInstance->pSharedInfo;
 
939
 
 
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;
 
944
        
 
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;
 
948
 
 
949
        /* Checking max playout events. */
 
950
        if ( f_pBufPlayoutGetEvent->ulMaxEvent > pSharedInfo->ChipConfig.ulSoftBufPlayoutEventsBufSize )
 
951
                return cOCT6100_ERR_BUFFER_PLAYOUT_MAX_EVENT;
 
952
 
 
953
        if ( f_pBufPlayoutGetEvent->fResetBufs == FALSE )
 
954
        {
 
955
                /* Check if events need to be fetched from the chip. */
 
956
                ulSoftReadPnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr;
 
957
                ulSoftWritePnt = pSharedInfo->SoftBufs.ulBufPlayoutEventBufferWritePtr;
 
958
 
 
959
                if ( ulSoftReadPnt == ulSoftWritePnt )
 
960
                {
 
961
                        ulResult = Oct6100BufferPlayoutTransferEvents( f_pApiInstance, f_pBufPlayoutGetEvent->fResetBufs );
 
962
                        if ( ulResult != cOCT6100_ERR_OK )
 
963
                                return ulResult;
 
964
                }
 
965
 
 
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;
 
971
 
 
972
                if ( ulSoftReadPnt != ulSoftWritePnt )
 
973
                {
 
974
                        ulNumEventsReturned = 0;
 
975
 
 
976
                        while( (ulSoftReadPnt != ulSoftWritePnt) && ( ulNumEventsReturned != f_pBufPlayoutGetEvent->ulMaxEvent) )
 
977
                        {
 
978
                                /* Get a pointer to the first event in the buffer. */
 
979
                                mOCT6100_GET_BUFFER_PLAYOUT_EVENT_BUF_PNT( pSharedInfo, pSoftEvent )
 
980
                                pSoftEvent += ulSoftReadPnt;
 
981
                                
 
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;
 
988
                                
 
989
                                /* Update the pointers of the soft buffer. */
 
990
                                ulSoftReadPnt++;
 
991
                                if ( ulSoftReadPnt == ulSoftBufSize )
 
992
                                        ulSoftReadPnt = 0;
 
993
 
 
994
                                ulNumEventsReturned++;
 
995
                        }
 
996
 
 
997
                        pSharedInfo->SoftBufs.ulBufPlayoutEventBufferReadPtr = ulSoftReadPnt;
 
998
 
 
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 ) */
 
1003
                        {
 
1004
                                f_pBufPlayoutGetEvent->fMoreEvents = FALSE;
 
1005
                                
 
1006
                                /* Remember this state in the interrupt manager. */
 
1007
                                pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE;
 
1008
                        }
 
1009
 
 
1010
                        f_pBufPlayoutGetEvent->ulNumValidEvent = ulNumEventsReturned;
 
1011
                }
 
1012
                else /* if ( ulSoftReadPnt == ulSoftWritePnt ) */
 
1013
                {
 
1014
                        /* No valid buffer playout events. */
 
1015
                        f_pBufPlayoutGetEvent->ulNumValidEvent = 0;             
 
1016
                        f_pBufPlayoutGetEvent->fMoreEvents = FALSE;
 
1017
 
 
1018
                        /* Remember this state in the interrupt manager. */
 
1019
                        pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE;
 
1020
                        
 
1021
                        return cOCT6100_ERR_BUFFER_PLAYOUT_EVENT_BUF_EMPTY;
 
1022
                }
 
1023
        }
 
1024
        else /* ( f_pEventGetPlayoutStop->fResetBufs == TRUE ) */
 
1025
        {
 
1026
                /* Check with the hardware first. */
 
1027
                ulResult = Oct6100BufferPlayoutTransferEvents( f_pApiInstance, f_pBufPlayoutGetEvent->fResetBufs );
 
1028
                if ( ulResult != cOCT6100_ERR_OK )
 
1029
                        return ulResult;
 
1030
 
 
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;
 
1034
 
 
1035
                f_pBufPlayoutGetEvent->fMoreEvents = FALSE;
 
1036
                f_pBufPlayoutGetEvent->ulNumValidEvent = 0;
 
1037
 
 
1038
                /* Remember this state in the interrupt manager. */
 
1039
                pSharedInfo->IntrptManage.fBufferPlayoutEventsPending = FALSE;
 
1040
        }
 
1041
 
 
1042
        return cOCT6100_ERR_OK;
 
1043
}
 
1044
#endif
 
1045
 
 
1046
 
 
1047
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
1048
 
 
1049
Function:               Oct6100BufferPlayoutTransferEvents
 
1050
 
 
1051
Description:    Check all channels that are currently playing a buffer and 
 
1052
                                generate an event if a buffer has stopped playing.
 
1053
 
 
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.
 
1059
 
 
1060
f_ulResetBuf                    Reset flag.
 
1061
 
 
1062
\*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
 
1063
#if !SKIP_Oct6100BufferPlayoutTransferEvents
 
1064
UINT32 Oct6100BufferPlayoutTransferEvents(
 
1065
                                IN OUT  tPOCT6100_INSTANCE_API                  f_pApiInstance,
 
1066
                                IN              UINT32                                                  f_ulResetBuf )
 
1067
{
 
1068
        tPOCT6100_SHARED_INFO                           pSharedInfo;
 
1069
        tPOCT6100_API_CHANNEL                           pEchoChannel;
 
1070
 
 
1071
        UINT32  ulChannelIndex;
 
1072
        UINT32  ulResult;
 
1073
        UINT32  ulLastBufPlayoutEventBufferOverflowCnt;
 
1074
 
 
1075
        /* Get local pointer(s). */
 
1076
        pSharedInfo = f_pApiInstance->pSharedInfo;
 
1077
 
 
1078
        /* If the buffer is to be reset then clear the overflow flag. */
 
1079
        if ( f_ulResetBuf == TRUE )
 
1080
        {
 
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;
 
1085
        }
 
1086
 
 
1087
        /* Check if buffer playout has been activated on some ports. */
 
1088
        if ( pSharedInfo->ChipStats.usNumberActiveBufPlayoutPorts == 0 )
 
1089
        {
 
1090
                /* Buffer playout has not been activated on any channel, */
 
1091
                /* let's not waste time here. */
 
1092
                return cOCT6100_ERR_OK;
 
1093
        }
 
1094
 
 
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;
 
1097
 
 
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++ )
 
1100
        {
 
1101
                mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, ulChannelIndex );
 
1102
                
 
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 )
 
1108
                {
 
1109
                        /* Read in the event only if there's enough room in the soft buffer. */
 
1110
                        if ( ulLastBufPlayoutEventBufferOverflowCnt == pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt )
 
1111
                        {
 
1112
                                /* Check Rout buffer playout first. */
 
1113
                                if ( ( pEchoChannel->fRinBufPlayoutNotifyOnStop == TRUE )
 
1114
                                        && ( pEchoChannel->fRinBufPlaying == TRUE ) )
 
1115
                                {
 
1116
                                        ulResult = Oct6100BufferPlayoutCheckForSpecificEvent( f_pApiInstance, ulChannelIndex, cOCT6100_CHANNEL_PORT_ROUT, TRUE, NULL );
 
1117
                                        if ( ulResult != cOCT6100_ERR_OK )
 
1118
                                                return ulResult;
 
1119
                                }
 
1120
                        }
 
1121
                        else /* if ( ulLastBufPlayoutEventBufferOverflowCnt != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt ) */
 
1122
                        {
 
1123
                                /* Get out of the loop, no more events can be inserted in the soft buffer. */
 
1124
                                break;
 
1125
                        }
 
1126
 
 
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 )
 
1130
                        {
 
1131
                                /* Check Sout buffer playout. */
 
1132
                                if ( ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == TRUE )
 
1133
                                        && ( pEchoChannel->fSoutBufPlaying == TRUE ) )
 
1134
                                {
 
1135
                                        ulResult = Oct6100BufferPlayoutCheckForSpecificEvent( f_pApiInstance, ulChannelIndex, cOCT6100_CHANNEL_PORT_SOUT, TRUE, NULL );
 
1136
                                        if ( ulResult != cOCT6100_ERR_OK )
 
1137
                                                return ulResult;
 
1138
                                }
 
1139
                        }
 
1140
                        else /* if ( ulLastBufPlayoutEventBufferOverflowCnt != pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt ) */
 
1141
                        {
 
1142
                                /* Get out of the loop, no more events can be inserted in the soft buffer. */
 
1143
                                break;
 
1144
                        }
 
1145
                }
 
1146
        }
 
1147
 
 
1148
        return cOCT6100_ERR_OK;
 
1149
}
 
1150
#endif
 
1151
 
 
1152
 
 
1153
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\
 
1154
 
 
1155
Function:               Oct6100BufferPlayoutCheckForSpecificEvent
 
1156
 
 
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.
 
1160
 
 
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.
 
1166
 
 
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.
 
1171
 
 
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 )
 
1180
{
 
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;
 
1186
 
 
1187
        UINT32  ulResult;
 
1188
        UINT16  usReadData;
 
1189
        UINT32  ulReadPtrBytesOfst;
 
1190
        UINT32  ulReadPtrBitOfst;
 
1191
        UINT32  ulReadPtrFieldSize;
 
1192
 
 
1193
        UINT32  ulWritePtrBytesOfst;
 
1194
        UINT32  ulWritePtrBitOfst;
 
1195
        UINT32  ulWritePtrFieldSize;
 
1196
 
 
1197
        UINT32  ulPlayoutBaseAddress;
 
1198
        UINT32  ulTempData;
 
1199
        UINT32  ulReadPtr;
 
1200
        UINT32  ulMask;
 
1201
        UINT32  ulWritePtr;
 
1202
        UINT32  ulUserEventId;
 
1203
        UINT32  ulEventType;
 
1204
 
 
1205
        /* Get local pointer(s). */
 
1206
        pSharedInfo = f_pApiInstance->pSharedInfo;
 
1207
 
 
1208
        /* Compare the read and write pointers for matching.  If they matched, playout stopped. */
 
1209
        mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pEchoChannel, f_ulChannelIndex );
 
1210
 
 
1211
        /* Set the playout feature base address. */
 
1212
        ulPlayoutBaseAddress = cOCT6100_CHANNEL_ROOT_BASE + ( f_ulChannelIndex * cOCT6100_CHANNEL_ROOT_SIZE ) + pSharedInfo->MemoryMap.ulChanRootConfOfst;
 
1213
 
 
1214
        if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_ROUT )
 
1215
        {
 
1216
                /* Check on the Rout port. */
 
1217
                ulUserEventId = pEchoChannel->ulRinUserBufPlayoutEventId;
 
1218
                ulEventType = pEchoChannel->byRinPlayoutStopEventType;
 
1219
 
 
1220
                ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.usDwordOffset * 4;
 
1221
                ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byBitOffset;
 
1222
                ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinWritePtrOfst.byFieldSize;
 
1223
 
 
1224
                ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.usDwordOffset * 4;
 
1225
                ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byBitOffset;
 
1226
                ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutRinReadPtrOfst.byFieldSize;
 
1227
        }
 
1228
        else /* if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_SOUT ) */
 
1229
        {
 
1230
                /* Check on the Sout port. */
 
1231
                ulUserEventId = pEchoChannel->ulSoutUserBufPlayoutEventId;
 
1232
                ulEventType = pEchoChannel->bySoutPlayoutStopEventType;
 
1233
 
 
1234
                ulWritePtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.usDwordOffset * 4;
 
1235
                ulWritePtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byBitOffset;
 
1236
                ulWritePtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutWritePtrOfst.byFieldSize;
 
1237
 
 
1238
                ulReadPtrBytesOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.usDwordOffset * 4;
 
1239
                ulReadPtrBitOfst = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byBitOffset;
 
1240
                ulReadPtrFieldSize = pSharedInfo->MemoryMap.PlayoutSoutReadPtrOfst.byFieldSize;
 
1241
        }
 
1242
 
 
1243
        /* Retrieve the current write pointer. */
 
1244
        mOCT6100_RETRIEVE_NLP_CONF_DWORD(       f_pApiInstance, 
 
1245
                                                                                pEchoChannel, 
 
1246
                                                                                ulPlayoutBaseAddress + ulWritePtrBytesOfst, 
 
1247
                                                                                &ulTempData,
 
1248
                                                                                ulResult );
 
1249
        if ( ulResult != cOCT6100_ERR_OK )
 
1250
                return ulResult;
 
1251
 
 
1252
        mOCT6100_CREATE_FEATURE_MASK( ulWritePtrFieldSize, ulWritePtrBitOfst, &ulMask );
 
1253
 
 
1254
        /* Store the write pointer.*/
 
1255
        ulWritePtr = ( ulTempData & ulMask ) >> ulWritePtrBitOfst;
 
1256
 
 
1257
        /* Read the read pointer.*/
 
1258
        ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
 
1259
 
 
1260
        ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
 
1261
        ReadParams.pusReadData = &usReadData;
 
1262
        ReadParams.ulReadAddress = ulPlayoutBaseAddress + ulReadPtrBytesOfst;
 
1263
 
 
1264
        /* Optimize this access by only reading the word we are interested in. */
 
1265
        if ( ulReadPtrBitOfst < 16 )
 
1266
                ReadParams.ulReadAddress += 2;
 
1267
 
 
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 )
 
1271
                return ulResult;
 
1272
 
 
1273
        /* Move data at correct position according to what was read. */
 
1274
        if ( ulReadPtrBitOfst < 16 )
 
1275
                ulTempData = usReadData;
 
1276
        else
 
1277
                ulTempData = usReadData << 16;
 
1278
        
 
1279
        mOCT6100_CREATE_FEATURE_MASK( ulReadPtrFieldSize, ulReadPtrBitOfst, &ulMask );
 
1280
        
 
1281
        /* Store the read pointer. */
 
1282
        ulReadPtr = ( ulTempData & ulMask ) >> ulReadPtrBitOfst;
 
1283
 
 
1284
        /* Playout has finished when the read pointer reaches the write pointer. */
 
1285
        if ( ulReadPtr != ulWritePtr )
 
1286
        {
 
1287
                /* Still playing -- do not generate an event. */
 
1288
                if ( f_pfEventDetected != NULL )
 
1289
                        *f_pfEventDetected = FALSE;
 
1290
        }
 
1291
        else
 
1292
        {
 
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 ) )
 
1297
                {
 
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;
 
1301
 
 
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;
 
1308
                        
 
1309
                        /* Generate millisecond timestamp. */
 
1310
                        GetTimeParms.pProcessContext = f_pApiInstance->pProcessContext;
 
1311
                        ulResult = Oct6100UserGetTime( &GetTimeParms );
 
1312
                        if ( ulResult != cOCT6100_ERR_OK )
 
1313
                                return ulResult;
 
1314
 
 
1315
                        pSoftEvent->ulTimestamp = ( GetTimeParms.aulWallTimeUs[ 0 ] / 1000 );
 
1316
                        pSoftEvent->ulTimestamp += ( GetTimeParms.aulWallTimeUs[ 1 ] ) * ( 0xFFFFFFFF / 1000 );
 
1317
 
 
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;
 
1322
 
 
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;
 
1326
                }
 
1327
                else if ( f_fSaveToSoftBuffer == TRUE ) 
 
1328
                {
 
1329
                        /* Set the overflow flag of the buffer. */
 
1330
                        pSharedInfo->SoftBufs.ulBufPlayoutEventBufferOverflowCnt++;
 
1331
                }
 
1332
 
 
1333
                /* Update the channel entry to set the playing flag to FALSE. */
 
1334
 
 
1335
                /* Select the port of interest. */
 
1336
                if ( f_ulChannelPort == cOCT6100_CHANNEL_PORT_ROUT )
 
1337
                {
 
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--;
 
1341
 
 
1342
                        pEchoChannel->fRinBufPlaying = FALSE;
 
1343
                        pEchoChannel->fRinBufPlayoutNotifyOnStop = FALSE;
 
1344
 
 
1345
                        /* Clear optimization flag if possible. */
 
1346
                        if ( ( pEchoChannel->fSoutBufPlaying == FALSE )
 
1347
                                && ( pEchoChannel->fSoutBufPlayoutNotifyOnStop == FALSE ) )
 
1348
                        {
 
1349
                                /* Buffer playout is no more active on this channel. */
 
1350
                                pEchoChannel->fBufPlayoutActive = FALSE;
 
1351
                        }
 
1352
                }
 
1353
                else /* f_ulChannelPort == cOCT6100_CHANNEL_PORT_SOUT */
 
1354
                {
 
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--;
 
1358
 
 
1359
                        pEchoChannel->fSoutBufPlaying = FALSE;
 
1360
                        pEchoChannel->fSoutBufPlayoutNotifyOnStop = FALSE;
 
1361
 
 
1362
                        /* Clear optimization flag if possible. */
 
1363
                        if ( ( pEchoChannel->fRinBufPlaying == FALSE )
 
1364
                                && ( pEchoChannel->fRinBufPlayoutNotifyOnStop == FALSE ) )
 
1365
                        {
 
1366
                                /* Buffer playout is no more active on this channel. */
 
1367
                                pEchoChannel->fBufPlayoutActive = FALSE;
 
1368
                        }
 
1369
                }
 
1370
 
 
1371
                /* Return that an event was detected. */
 
1372
                if ( f_pfEventDetected != NULL )
 
1373
                        *f_pfEventDetected = TRUE;
 
1374
        }
 
1375
        
 
1376
        return cOCT6100_ERR_OK;
 
1377
}
 
1378
#endif
 
1379
 
 
1380