blob: 787dfda6aaf01c4311b1800c07659629a8ca4344 [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001/*****************************************************************************
2* Copyright Statement:
3* --------------------
4* This software is protected by Copyright and the information contained
5* herein is confidential. The software may not be copied and the information
6* contained herein may not be used or disclosed except with the written
7* permission of MediaTek Inc. (C) 2011
8*
9* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
10* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
11* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
12* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
13* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
14* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
15* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
16* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
17* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
18* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
19* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
20* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
21*
22* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
23* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
24* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
25* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
26* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
27*
28* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
29* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
30* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
31* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
32* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
33*
34*****************************************************************************/
35
36/*******************************************************************************
37 *
38 * Filename:
39 * ---------
40 * eCall_drv.c
41 *
42 * Project:
43 * --------
44 * MAUI
45 *
46 * Description:
47 * ------------
48 * eCall Modem Driver
49 *
50 * Author:
51 * -------
52 * -------
53 *
54 *==============================================================================
55 * HISTORY
56 * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
57 *------------------------------------------------------------------------------
58 * removed!
59 * removed!
60 * removed!
61 *
62 * removed!
63 * removed!
64 * removed!
65 * removed!
66 *
67 * removed!
68 * removed!
69 *
70 * removed!
71 * removed!
72 * removed!
73 * removed!
74 *
75 * removed!
76 * removed!
77 * removed!
78 * removed!
79 *
80 * removed!
81 * removed!
82 * removed!
83 * removed!
84 *
85 * removed!
86 * removed!
87 * removed!
88 * removed!
89 *
90 * removed!
91 * removed!
92 * removed!
93 * removed!
94 *
95 * removed!
96 * removed!
97 * removed!
98 *
99 * removed!
100 * removed!
101 * removed!
102 *
103 * removed!
104 * removed!
105 * removed!
106 * removed!
107 *
108 * removed!
109 * removed!
110 * removed!
111 *
112 * removed!
113 * removed!
114 *
115 * removed!
116 * removed!
117 * removed!
118 *
119 * removed!
120 * removed!
121 * removed!
122 *
123 * removed!
124 * removed!
125 * removed!
126 *
127 * removed!
128 * removed!
129 * removed!
130 *
131 * removed!
132 * removed!
133 * removed!
134 *
135 * removed!
136 * removed!
137 * removed!
138 *
139 * removed!
140 * removed!
141 * removed!
142 *
143 * removed!
144 * removed!
145 * removed!
146 *
147 * removed!
148 * removed!
149 * removed!
150 *
151 * removed!
152 * removed!
153 * removed!
154 *
155 * removed!
156 *------------------------------------------------------------------------------
157 * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
158 *==============================================================================
159 *******************************************************************************/
160
161#include <stdio.h>
162#include "ecall_defines.h"
163#include "ecall_control.h"
164#include "modemx.h"
165
166#include "kal_public_api.h"
167#include "kal_trace.h"
168#include "l1sp_trc.h"
169#include "l1audio.h"
170#include "pcm4way.h"
171#include "am.h"
172#include "media.h"
173#include "sp_enhance.h"
174#include "bli_exp.h"
175#include "spc_drv.h"
176#include "sal_def.h"
177#include "sal_exp.h"
178
179
180Int16 eCall_TX_CTRL_SEQ_State[800];
181Int16 eCall_TX_CTRL_SEQ_dlData[800];
182Int16 eCall_TX_CTRL_SEQ_dlMetric[800];
183Int16 eCall_RX_CTRL_SEQ_State[800];
184Int16 eCall_RX_CTRL_SEQ_dlData[800];
185Int16 eCall_RX_CTRL_SEQ_dlMetric[800];
186Int16 eCall_RX_Ctrl_Index;
187
188#define PCM_FIFO_LEN 2 // could be 1 ~ N
189#define ECALL_SWB_BUF_LEN 640 // 32k*20ms = 640
190#define ECALL_WB_BUF_LEN 320 // 16k*20ms = 320
191#define ECALL_NB_BUF_LEN 160 // 8k*20ms = 160
192
193typedef enum {
194 Udef = -1, Ivs, IvsRx, IvsTx, Psap, PsapRx, PsapTx
195} RunMode;
196
197typedef struct {
198 RunMode mode;
199
200 kal_bool ivsPush;
201 kal_bool msdReceived;
202 kal_bool msdSet;
203 kal_uint8 aud_id;
204 kal_uint8 Ctrl_Par_Switch;
205 kal_bool TxRx;
206
207 int frameStartHlack;
208 int frameStartHlackCur;
209
210 Ord8 NewMsd[ECALL_MSD_MAX_LENGTH];
211 Ord8 CurMsd[ECALL_MSD_MAX_LENGTH];
212
213 // For PCM4Way
214 kal_uint16 pcm_fifo_read;
215 kal_uint16 pcm_fifo_write;
216 kal_uint16 next_to_process;
217 kal_uint16 reserve_2byte;
218
219 // speech-channel PCM buffer
220 // Input from PCM4WAY
221 kal_uint16 ul_pcm_input[2*PCM_FIFO_LEN][ECALL_SWB_BUF_LEN]; // input buffer size = 640
222 kal_uint16 dl_pcm_input[2*PCM_FIFO_LEN][ECALL_SWB_BUF_LEN];
223
224 kal_uint16 ul_pcm_input_len[2*PCM_FIFO_LEN];
225 kal_uint16 dl_pcm_input_len[2*PCM_FIFO_LEN];
226
227 // SRC temp buffer (NB 8k only)
228 kal_uint16 ul_pcm_fifo[2*PCM_FIFO_LEN][ECALL_NB_BUF_LEN]; // input buffer size = 160
229 kal_uint16 dl_pcm_fifo[2*PCM_FIFO_LEN][ECALL_NB_BUF_LEN];
230
231 // Output to PCM4WAY
232 kal_uint16 ul_pcm_output_nb[2*PCM_FIFO_LEN][ECALL_NB_BUF_LEN]; //160
233 kal_uint16 ul_pcm_output_wb[2*PCM_FIFO_LEN][ECALL_WB_BUF_LEN]; //320
234 kal_uint16 ul_pcm_output_swb[2*PCM_FIFO_LEN][ECALL_SWB_BUF_LEN]; //640
235
236 kal_bool isUpdateUL[2*PCM_FIFO_LEN];
237
238 // SRC handler internal buffer
239 // 32k <-> 8k
240 kal_uint8 internal_buf_ul_out[2184]; // internal buffer for src
241 kal_uint8 internal_buf_dl_in[2184]; // internal buffer for src
242 // 16k <-> 8k
243 kal_uint8 internal_buf_ul_out2[2184]; // internal buffer for src
244 kal_uint8 internal_buf_dl_in2[2184]; // internal buffer for src
245
246
247 BLI_HANDLE * dl_downsample_16_8;
248 BLI_HANDLE * dl_downsample_32_8;
249 BLI_HANDLE * ul_upsample_8_16;
250 BLI_HANDLE * ul_upsample_8_32;
251
252 // For HRT
253 kal_uint16 HRT_status;
254 kal_uint16 HRT_status_backup;
255
256 eCall_Callback handler;
257
258 void *allocMem;
259} EcallShell;
260
261static EcallShell *eCallModemIVS;
262static EcallShell *eCallModemPSAP;
263
264kal_enhmutexid eCall_mutex;
265
266/*------------------------------------------------*/
267/* The private functions of eCall modem driver. */
268/*------------------------------------------------*/
269//#pragma arm section code="SECONDARY_ROCODE"
270void eCall_Init(void)
271{
272 eCall_mutex= kal_create_enh_mutex( "ECALL_MUTEX" );
273}
274
275static void eCall_HRT_Set(void)
276{
277 eCallModemIVS->HRT_status = 1;
278}
279
280static void eCall_HRT_Clean(void)
281{
282 eCallModemIVS->HRT_status = 0;
283}
284
285static void eCall_IVS_hisr(void)
286{
287 kal_uint16 read_idx, write_idx;
288
289 if (eCallModemIVS == NULL)
290 return;
291
292 read_idx = eCallModemIVS->pcm_fifo_read;
293 write_idx = eCallModemIVS->pcm_fifo_write;
294
295 if (eCallModemIVS->pcm_fifo_read == eCallModemIVS->next_to_process) {
296 // Processed data isn't enough
297 if(spc_Get_Ecall_Lib_Status()==SPC_ECALL_ENABLE ){
298 PCM4WAY_FillSE(0);
299 PCM4WAY_FillSpk(0);
300 }
301
302 } else {
303 if(spc_Get_Ecall_Lib_Status()==SPC_ECALL_ENABLE ) {
304 // uplink-path
305 if (eCallModemIVS->isUpdateUL[read_idx] == KAL_FALSE) {
306 PCM4WAY_PutToSE((const uint16*)(eCallModemIVS->ul_pcm_input[read_idx]));
307
308 } else {
309 uint16 bufLen = SAL_PcmEx_GetBufLen(SAL_PCMEX_PNW_BUF_M2D_UL1);
310 if(ECALL_NB_BUF_LEN == bufLen) {
311 PCM4WAY_PutToSE((const uint16*)(eCallModemIVS->ul_pcm_output_nb[read_idx]));
312
313 } else if(ECALL_WB_BUF_LEN == bufLen) {
314 PCM4WAY_PutToSE((const uint16*)(eCallModemIVS->ul_pcm_output_wb[read_idx]));
315
316 } else {
317 PCM4WAY_PutToSE((const uint16*)(eCallModemIVS->ul_pcm_output_swb[read_idx]));
318 }
319
320 eCallModemIVS->isUpdateUL[read_idx] = KAL_FALSE;
321 MD_TRC_ECALL_IVS_PCM_UPDATE_PUTTOSE(read_idx, bufLen);
322 }
323
324 // downlink-path no change
325 PCM4WAY_PutToSpk((const uint16*)(eCallModemIVS->dl_pcm_input[read_idx]));
326 }
327
328 // Update index
329 eCallModemIVS->pcm_fifo_write++;
330 if (eCallModemIVS->pcm_fifo_write == 2*PCM_FIFO_LEN) {
331 eCallModemIVS->pcm_fifo_write = 0;
332 }
333 }
334 if (read_idx != write_idx) {
335 // There is enough space to write data from microphone
336 eCallModemIVS->ul_pcm_input_len[write_idx] = PCM4WAY_GetFromMic((uint16*)(eCallModemIVS->ul_pcm_input[write_idx]));
337 eCallModemIVS->dl_pcm_input_len[write_idx] = PCM4WAY_GetFromSD((uint16*)(eCallModemIVS->dl_pcm_input[write_idx]));
338 MD_TRC_ECALL_IVS_PCM_INPUT_LEN(write_idx, eCallModemIVS->ul_pcm_input_len[write_idx], write_idx, eCallModemIVS->dl_pcm_input_len);
339
340 // Update index
341 eCallModemIVS->pcm_fifo_read++;
342 if (eCallModemIVS->pcm_fifo_read == 2*PCM_FIFO_LEN) {
343 eCallModemIVS->pcm_fifo_read = 0;
344 }
345 }
346
347 eCallModemIVS->HRT_status_backup = eCallModemIVS->HRT_status;
348 eCall_HRT_Set();
349
350 L1Audio_SetEvent(eCallModemIVS->aud_id, (void*)0);
351}
352//#pragma arm section
353
354static void eCall_IVS_ProcessFrame(void)
355{
356 kal_uint32 proc_idx;
357
358 // Here we only do DL downsample, UL upsample
359 kal_uint32 dl_ds_inLen, dl_ds_outLen;
360 kal_uint32 ul_us_inLen, ul_us_outLen;
361
362 kal_uint16 *p_dl_ds_inBuf, *p_dl_ds_outBuf;
363 kal_uint16 *p_ul_us_inBuf, *p_ul_us_outBuf;
364
365 if (eCallModemIVS == NULL)
366 return;
367
368 proc_idx = eCallModemIVS->next_to_process;
369
370 switch (eCallModemIVS->mode) {
371 case Ivs:
372 if (eCallModemIVS->ivsPush == KAL_TRUE) {
373 IvsSendStart();
374 eCallModemIVS->ivsPush = KAL_FALSE;
375 }
376
377 /******************************************************
378 * dl_pcm_input -> dl_pcm_fifo -> dl_pcm_output *
379 * 32k 8k 32k *
380 * [BAUDOT] -> [ECALLLIB] *
381 ******************************************************/
382
383 /* [ECALL blisrc] DL downsample start */
384 p_dl_ds_inBuf = eCallModemIVS->dl_pcm_input[proc_idx];
385 p_dl_ds_outBuf = eCallModemIVS->dl_pcm_fifo[proc_idx];
386
387 if(ECALL_WB_BUF_LEN == eCallModemIVS->dl_pcm_input_len[proc_idx]) {
388 dl_ds_inLen = ECALL_WB_BUF_LEN << 1;
389 dl_ds_outLen = ECALL_NB_BUF_LEN << 1;
390 BLI_Convert(eCallModemIVS->dl_downsample_16_8, (short *)p_dl_ds_inBuf, &dl_ds_inLen, (short *)p_dl_ds_outBuf, &dl_ds_outLen);
391
392 } else if(ECALL_SWB_BUF_LEN ==eCallModemIVS->dl_pcm_input_len[proc_idx]) {
393 dl_ds_inLen = ECALL_SWB_BUF_LEN << 1;
394 dl_ds_outLen = ECALL_NB_BUF_LEN << 1;
395 BLI_Convert(eCallModemIVS->dl_downsample_32_8, (short *)p_dl_ds_inBuf, &dl_ds_inLen, (short *)p_dl_ds_outBuf, &dl_ds_outLen);
396
397 } else{
398 memcpy(p_dl_ds_outBuf, p_dl_ds_inBuf, ECALL_NB_BUF_LEN << 1);
399 }
400 /* [ECALL blisrc] DL downsample end */
401
402#if 1
403 {
404 IvsState preRxState = IvsRxGetState();
405 IvsState curState;
406
407 IvsProcess((Int16 *)eCallModemIVS->dl_pcm_fifo[proc_idx]);
408
409 curState = IvsTxGetState();
410 if ((curState == IvsTrigger) || (curState == IvsStart) || (curState == IvsSendMsd) || (preRxState != IvsIdle) || (IvsRxGetState() != IvsIdle)) {
411 memcpy(eCallModemIVS->ul_pcm_fifo[proc_idx], eCallModemIVS->dl_pcm_fifo[proc_idx], ECALL_NB_BUF_LEN*sizeof(kal_uint16));
412
413 /*****************************************************
414 * dl_pcm_output <- dl_pcm_fifo <- dl_pcm_input *
415 * 32k 8k 32k *
416 * [ECALLLIB] <- [BAUDOT] *
417 *****************************************************/
418
419 /* [ECALL blisrc] UL up sampling start */
420 //NB output
421 p_ul_us_inBuf = eCallModemIVS->ul_pcm_fifo[proc_idx];
422 p_ul_us_outBuf = eCallModemIVS->ul_pcm_output_nb[proc_idx];
423 memcpy(p_ul_us_outBuf, p_ul_us_inBuf, ECALL_NB_BUF_LEN << 1);
424
425 //WB output
426 ul_us_inLen = ECALL_NB_BUF_LEN << 1;
427 ul_us_outLen = ECALL_WB_BUF_LEN << 1;
428 p_ul_us_outBuf = eCallModemIVS->ul_pcm_output_wb[proc_idx];
429 BLI_Convert(eCallModemIVS->ul_upsample_8_16, (short *)p_ul_us_inBuf, &ul_us_inLen, (short *)p_ul_us_outBuf, &ul_us_outLen);
430
431 //SWB output
432 ul_us_inLen = ECALL_NB_BUF_LEN << 1;
433 ul_us_outLen = ECALL_SWB_BUF_LEN << 1;
434 p_ul_us_outBuf = eCallModemIVS->ul_pcm_output_swb[proc_idx];
435 BLI_Convert(eCallModemIVS->ul_upsample_8_32, (short *)p_ul_us_inBuf, &ul_us_inLen, (short *)p_ul_us_outBuf, &ul_us_outLen);
436 /* [ECALL blisrc] UL up sampling end */
437
438 eCallModemIVS->isUpdateUL[proc_idx] = KAL_TRUE;
439 MD_TRC_ECALL_IVS_PCM_UPDATE_UL(proc_idx, curState, proc_idx, eCallModemIVS->isUpdateUL[proc_idx]);
440 }
441 }
442
443#else
444/* under construction !*/
445/* under construction !*/
446/* under construction !*/
447/* under construction !*/
448/* under construction !*/
449#endif
450
451 break;
452 case IvsRx:
453 if (eCallModemIVS->ivsPush == KAL_TRUE) {
454 IvsSendStart();
455 eCallModemIVS->ivsPush = KAL_FALSE;
456 }
457
458 /******************************************************
459 * dl_pcm_input -> dl_pcm_fifo -> dl_pcm_output *
460 * 32k 8k 32k *
461 * [BAUDOT] -> [ECALLLIB] *
462 ******************************************************/
463
464 /* [ECALL blisrc] DL downsample start */
465 p_dl_ds_inBuf = eCallModemIVS->dl_pcm_input[proc_idx];
466 p_dl_ds_outBuf = eCallModemIVS->dl_pcm_fifo[proc_idx];
467
468 if(ECALL_WB_BUF_LEN == eCallModemIVS->dl_pcm_input_len[proc_idx]) {
469 dl_ds_inLen = ECALL_WB_BUF_LEN << 1;
470 dl_ds_outLen = ECALL_NB_BUF_LEN << 1;
471 BLI_Convert(eCallModemIVS->dl_downsample_16_8, (short *)p_dl_ds_inBuf, &dl_ds_inLen, (short *)p_dl_ds_outBuf, &dl_ds_outLen);
472
473 } else if(ECALL_SWB_BUF_LEN ==eCallModemIVS->dl_pcm_input_len[proc_idx]) {
474 dl_ds_inLen = ECALL_SWB_BUF_LEN << 1;
475 dl_ds_outLen = ECALL_NB_BUF_LEN << 1;
476 BLI_Convert(eCallModemIVS->dl_downsample_32_8, (short *)p_dl_ds_inBuf, &dl_ds_inLen, (short *)p_dl_ds_outBuf, &dl_ds_outLen);
477
478 } else{
479 memcpy(p_dl_ds_outBuf, p_dl_ds_inBuf, ECALL_NB_BUF_LEN << 1);
480 }
481 /* [ECALL blisrc] DL downsample end */
482
483#if 1
484 {
485 IvsState preRxState = IvsRxGetState();
486 IvsState curState;
487
488 IvsProcess((Int16 *)eCallModemIVS->dl_pcm_fifo[proc_idx]);
489
490 curState = IvsTxGetState();
491 if ((curState == IvsTrigger) || (curState == IvsStart) || (curState == IvsSendMsd) || (preRxState != IvsIdle) || (IvsRxGetState() != IvsIdle)) {
492 memcpy(eCallModemIVS->ul_pcm_fifo[proc_idx], eCallModemIVS->dl_pcm_fifo[proc_idx], ECALL_NB_BUF_LEN*sizeof(kal_uint16));
493
494 /*****************************************************
495 * dl_pcm_output <- dl_pcm_fifo <- dl_pcm_input *
496 * 32k 8k 32k *
497 * [ECALLLIB] <- [BAUDOT] *
498 *****************************************************/
499
500 /* [ECALL blisrc] UL up sampling start */
501 //NB output
502 p_ul_us_inBuf = eCallModemIVS->ul_pcm_fifo[proc_idx];
503 p_ul_us_outBuf = eCallModemIVS->ul_pcm_output_nb[proc_idx];
504 memcpy(p_ul_us_outBuf, p_ul_us_inBuf, ECALL_NB_BUF_LEN << 1);
505
506 //WB output
507 ul_us_inLen = ECALL_NB_BUF_LEN << 1;
508 ul_us_outLen = ECALL_WB_BUF_LEN << 1;
509 p_ul_us_outBuf = eCallModemIVS->ul_pcm_output_wb[proc_idx];
510 BLI_Convert(eCallModemIVS->ul_upsample_8_16, (short *)p_ul_us_inBuf, &ul_us_inLen, (short *)p_ul_us_outBuf, &ul_us_outLen);
511
512 //SWB output
513 ul_us_inLen = ECALL_NB_BUF_LEN << 1;
514 ul_us_outLen = ECALL_SWB_BUF_LEN << 1;
515 p_ul_us_outBuf = eCallModemIVS->ul_pcm_output_swb[proc_idx];
516 BLI_Convert(eCallModemIVS->ul_upsample_8_32, (short *)p_ul_us_inBuf, &ul_us_inLen, (short *)p_ul_us_outBuf, &ul_us_outLen);
517 /* [ECALL blisrc] UL up sampling end */
518
519 eCallModemIVS->isUpdateUL[proc_idx] = KAL_TRUE;
520 MD_TRC_ECALL_IVS_PCM_UPDATE_UL(proc_idx, curState, proc_idx, eCallModemIVS->isUpdateUL[proc_idx]);
521 }
522 }
523#else
524/* under construction !*/
525/* under construction !*/
526/* under construction !*/
527/* under construction !*/
528#endif
529
530 break;
531 default:
532 ASSERT(0);
533 break;
534 }
535}
536
537static void eCall_IVS_ProcessTask(void *data)
538{
539 kal_take_enh_mutex( eCall_mutex);
540 if (eCallModemIVS == NULL) {
541 kal_give_enh_mutex( eCall_mutex);
542 return;
543 }
544
545 if (eCallModemIVS->HRT_status_backup != 0)
546 {
547 MD_TRC_ECALL_IVS_HRT_STATUS(eCallModemIVS->HRT_status_backup);
548 }
549
550 while (eCallModemIVS->next_to_process != eCallModemIVS->pcm_fifo_write) {
551 // Process each frame
552 eCall_IVS_ProcessFrame();
553
554 // Update index
555 eCallModemIVS->next_to_process++;
556 if (eCallModemIVS->next_to_process == 2 * PCM_FIFO_LEN) {
557 eCallModemIVS->next_to_process = 0;
558 }
559
560 eCall_HRT_Clean();
561 }
562 kal_give_enh_mutex( eCall_mutex);
563}
564
565static void eCall_IVS_OnHandler( void *data )
566{
567 (void)data;
568 if(spc_Get_Ecall_Lib_Status()==SPC_ECALL_ENABLE )
569 {
570
571 PCM4WAY_Start(eCall_IVS_hisr, 0);
572 }
573 else
574 {
575 PCM4WAY_Start(eCall_IVS_hisr, 4);
576 }
577}
578
579static void eCall_IVS_OffHandler( void *data )
580{
581 (void)data;
582
583 PCM4WAY_Stop(0);
584}
585
586/*------------------------------------------------*/
587/* The public functions of eCall modem driver. */
588/*------------------------------------------------*/
589eCall_Modem_Status eCall_IVS_Open(eCall_Callback handler)
590{
591 ASSERT( handler != NULL );
592
593 MD_TRC_ECALL_IVS_DRV_OPEN(spc_Get_Ecall_Lib_Status());
594
595 if (eCallModemPSAP != NULL) {
596 return eCALL_OPERATION_FAIL;
597 }
598
599 if ( eCallModemIVS != NULL ) {
600 return eCALL_OPERATION_ALREADY_OPEN;
601 }
602
603 //L1SP_EnableSpeechEnhancement(KAL_FALSE);
604
605 //eCallModemIVS = (EcallShell *)audio_alloc_mem_cacheable( sizeof(EcallShell) );
606 eCallModemIVS = (EcallShell *)get_ctrl_buffer( sizeof(EcallShell) );
607 ASSERT( eCallModemIVS != NULL );
608 memset(eCallModemIVS, 0, sizeof(EcallShell));
609
610 // Allocate for IVS internal structure
611 {
612 kal_uint32 reqSize;
613
614 reqSize = (kal_uint32) IvsGetMemSize();
615 // eCallModemIVS->allocMem = (void *)audio_alloc_mem_cacheable( reqSize );
616 eCallModemIVS->allocMem = (void *)get_ctrl_buffer( reqSize );
617 memset(eCallModemIVS->allocMem, 0, sizeof(reqSize));
618 IvsInit( eCallModemIVS->allocMem );
619
620 if (eCallModemIVS->allocMem == NULL) {
621 MD_TRC_ECALL_IVS_DRV_ALLOCMEM_NULL();
622 }
623 }
624
625 // open BLI Src for ecall
626 // 32k <-> 8k
627 eCallModemIVS->dl_downsample_32_8 = BLI_Open(32000, 1, 8000, 1, (signed char*)eCallModemIVS->internal_buf_dl_in, 0); // open DL down sampling src
628 eCallModemIVS->ul_upsample_8_32 = BLI_Open(8000, 1, 32000, 1, (signed char*)eCallModemIVS->internal_buf_ul_out, 0); // open UL up sampling src
629 // 16k <-> 8k
630 eCallModemIVS->dl_downsample_16_8 = BLI_Open(16000, 1, 8000, 1, (signed char*)eCallModemIVS->internal_buf_dl_in2, 0); // open DL down sampling src
631 eCallModemIVS->ul_upsample_8_16 = BLI_Open(8000, 1, 16000, 1, (signed char*)eCallModemIVS->internal_buf_ul_out2, 0); // open UL up sampling src
632
633 eCallModemIVS->aud_id = L1Audio_GetAudioID();
634 L1Audio_SetEventHandler(eCallModemIVS->aud_id , eCall_IVS_ProcessTask);
635 L1Audio_SetFlag(eCallModemIVS->aud_id);
636
637 IvsRxReset();
638
639 eCallModemIVS->mode = IvsRx;
640 eCallModemIVS->pcm_fifo_read = 0;
641 eCallModemIVS->pcm_fifo_write = PCM_FIFO_LEN;
642 eCallModemIVS->next_to_process = PCM_FIFO_LEN;
643 eCallModemIVS->handler = handler;
644
645 for (int i=0; i<2*PCM_FIFO_LEN; i++) {
646 eCallModemIVS->isUpdateUL[i] = KAL_FALSE;
647 }
648
649 //Init eCall RX ctrl seq
650 memset(eCall_RX_CTRL_SEQ_State, 0, 800*sizeof(Int16));
651 memset(eCall_RX_CTRL_SEQ_dlData, 0, 800*sizeof(Int16));
652 memset(eCall_RX_CTRL_SEQ_dlMetric, 0, 800*sizeof(Int16));
653 eCall_RX_Ctrl_Index = 1;
654 eCall_RX_CTRL_SEQ_dlMetric[0] = 0xFF;
655 eCall_RX_CTRL_SEQ_State[0] = 0xDD;
656 eCall_RX_CTRL_SEQ_dlData[0] = 0xEE;
657
658 if(spc_Get_Ecall_Lib_Status()==SPC_ECALL_SDT_ONLY ){
659 Ivs_Set_Ecall_Lib_Status(Ivs_ECALL_SDT_ONLY);
660 }else if(spc_Get_Ecall_Lib_Status()==SPC_ECALL_ENABLE){
661 Ivs_Set_Ecall_Lib_Status(Ivs_ECALL_ENABLE);
662 }else {
663 return eCALL_OPERATION_FAIL;
664 }
665
666 if ( AM_IsSpeechOn() ) {
667 eCall_IVS_OnHandler( (void *)0 );
668 }
669
670 // Hook service to L1SP
671 L1SP_Register_Pcm4WayService( eCall_IVS_OnHandler, eCall_IVS_OffHandler );
672
673 return eCALL_OPERATION_SUCCESS;
674}
675
676eCall_Modem_Status eCall_IVS_Close(void)
677{
678 MD_TRC_ECALL_IVS_DRV_CLOSE();
679 kal_take_enh_mutex( eCall_mutex);
680 if ( eCallModemIVS == NULL ) {
681 kal_give_enh_mutex( eCall_mutex);
682 return eCALL_OPERATION_ALREADY_CLOSE;
683 }
684
685 if (eCallModemPSAP != NULL) {
686 kal_give_enh_mutex( eCall_mutex);
687 return eCALL_OPERATION_FAIL;
688 }
689
690 if(spc_Get_Ecall_Lib_Status()==SPC_ECALL_DISABLE){
691 kal_give_enh_mutex( eCall_mutex);
692 return eCALL_OPERATION_FAIL;
693 }
694 // Unhook service to L1SP
695 L1SP_UnRegister_Pcm4Way_Service();
696
697 if ( AM_IsSpeechOn() ) {
698 eCall_IVS_OffHandler( (void *)0 );
699 }
700
701 L1Audio_ClearFlag(eCallModemIVS->aud_id);
702 L1Audio_FreeAudioID(eCallModemIVS->aud_id);
703
704 BLI_Close(eCallModemIVS->dl_downsample_16_8, 0); // Close DL down sampling src
705 BLI_Close(eCallModemIVS->dl_downsample_32_8, 0); // Close DL down sampling src
706 BLI_Close(eCallModemIVS->ul_upsample_8_16, 0); // Close UL up sampling src
707 BLI_Close(eCallModemIVS->ul_upsample_8_32, 0); // Close UL up sampling src
708
709 // Deallocate for IVS internal structure
710 {
711 IvsDeinit();
712 if (eCallModemIVS->allocMem == NULL) {
713 MD_TRC_ECALL_IVS_DRV_ALLOCMEM_NULL();
714
715 } else {
716 free_ctrl_buffer( (void *) eCallModemIVS->allocMem );
717 }
718 }
719
720 free_ctrl_buffer( (void *) eCallModemIVS );
721 //L1SP_EnableSpeechEnhancement(KAL_TRUE);
722 eCallModemIVS = NULL;
723
724 //transfer ctrl data to AP
725 spc_eCall_RX_CTRL_Data(0xDD);
726 spc_eCall_RX_CTRL_Data(0xEE);
727 spc_eCall_RX_CTRL_Data(0xFF);
728
729 kal_give_enh_mutex( eCall_mutex);
730 return eCALL_OPERATION_SUCCESS;
731}
732
733eCall_Modem_Status eCall_IVS_PutMSD(const kal_uint8 *pMSD, const kal_uint32 uLen, kal_uint8 from)
734{
735 kal_uint8 i=0;
736 if (eCallModemPSAP != NULL) {
737 return eCALL_OPERATION_FAIL;
738 }
739
740 if ( eCallModemIVS == NULL ) {
741 return eCALL_OPERATION_FAIL;
742 }
743 if(spc_Get_Ecall_Lib_Status()==SPC_ECALL_SDT_ONLY)
744 {
745 return eCALL_OPERATION_STOP;
746 }
747 ASSERT( pMSD != NULL );
748 ASSERT( uLen <= ECALL_MSD_MAX_LENGTH);
749
750 memset(eCallModemIVS->NewMsd, 0, ECALL_MSD_MAX_LENGTH*sizeof(Ord8));
751 memcpy(eCallModemIVS->NewMsd, pMSD, uLen*sizeof(Ord8));
752// for(i=0;i<140;i=i+7)
753// {
754// MD_TRC_ECALL_IVS_DRV_PUT_MSD(pMSD[i],pMSD[i+1],pMSD[i+2],pMSD[i+3],pMSD[i+4],pMSD[i+5],pMSD[i+6]);
755// }
756 // Check status and copy to current MSD
757 //if ( IvsTxGetState() == IvsIdle ) {
758 memcpy(eCallModemIVS->CurMsd, eCallModemIVS->NewMsd, ECALL_MSD_MAX_LENGTH*sizeof(Ord8));
759 //}
760 for(i=0;i<140;i=i+7)
761 {
762 MD_TRC_ECALL_IVS_DRV_PUT_MSD(eCallModemIVS->CurMsd[i],eCallModemIVS->CurMsd[i+1],eCallModemIVS->CurMsd[i+2],eCallModemIVS->CurMsd[i+3],eCallModemIVS->CurMsd[i+4],eCallModemIVS->CurMsd[i+5],eCallModemIVS->CurMsd[i+6]);
763 }
764
765 // 0: Internal, 1:L5
766 if (from == 1) {
767 eCallModemIVS->msdSet = KAL_TRUE;
768 }
769 MD_TRC_ECALL_IVS_DRV_MSD_SET(from, eCallModemIVS->msdSet);
770
771 IvsTxReset(eCallModemIVS->CurMsd, ECALL_MSD_MAX_LENGTH);
772
773 return eCALL_OPERATION_SUCCESS;
774}
775
776eCall_Modem_Status eCall_IVS_SendStart(void)
777{
778 MD_TRC_ECALL_IVS_DRV_SEND_START();
779 if (eCallModemPSAP != NULL) {
780 return eCALL_OPERATION_FAIL;
781 }
782
783 if ( eCallModemIVS == NULL ) {
784 return eCALL_OPERATION_FAIL;
785 }
786
787 // Check state
788 if ( IvsTxGetState() != IvsIdle ) {
789 return eCALL_OPERATION_DURING_TRANSMISSION;
790 }
791 if(spc_Get_Ecall_Lib_Status()==SPC_ECALL_DISABLE){
792 return eCALL_OPERATION_FAIL;
793 }
794 eCallModemIVS->TxRx = KAL_TRUE;
795 IvsRxReset();
796
797 if (eCallModemIVS->msdSet) {
798 eCallModemIVS->mode = Ivs;
799 }
800
801 eCallModemIVS->ivsPush = KAL_TRUE;
802
803 return eCALL_OPERATION_SUCCESS;
804}
805
806
807#if 1
808/*------------------------------------------------*/
809/* The unit test code for callback. */
810/*------------------------------------------------*/
811
812void IvsCatchEvent(IvsEvent ie)
813{
814 ASSERT(eCallModemIVS);
815
816 MD_TRC_ECALL_IVS_DRV_CATCH_EVENT(ie);
817
818 /* custom event handlers to be implemented here... */
819 /* see modemx.h for a list of possible events (enum IvsEvent) */
820 switch (ie) {
821 case IVSEVENT_SENDINGMSD:
822 #if defined(__L5_SUPPORT__)
823 if (eCallModemIVS->msdSet) {
824 spc_L5ECALL_Status_Info_Callback(0xE1,0);
825 } else {
826 MD_TRC_ECALL_IVS_DRV_MSD_NOT_SET();
827 }
828 #else
829 spc_eCall_Handshake_Info_Notify(0xE1,0);
830 #endif
831 break;
832 case IVSEVENT_CONTROLLOCK:
833 eCallModemIVS->mode = Ivs;
834 eCallModemIVS->TxRx = KAL_TRUE;
835 eCallModemIVS->handler( eCALL_EVENT_RECV_START, NULL);
836 break;
837 case IVSEVENT_NACKRECEIVED:
838 eCallModemIVS->handler( eCALL_EVENT_RECV_NACK, NULL);
839 break;
840 case IVSEVENT_LLACKRECEIVED:
841 #if defined(__L5_SUPPORT__)
842 spc_L5ECALL_Status_Info_Callback(0xE2,0);
843 #else
844 spc_eCall_Handshake_Info_Notify(0xE2,0);
845 #endif
846 eCallModemIVS->handler( eCALL_EVENT_RECV_LL_ACK, NULL);
847 break;
848 case IVSEVENT_HLACKRECEIVED:
849 eCallModemIVS->mode = IvsRx;
850 break;
851 case IVSEVENT_RECEIVESTART:
852 #if defined(__L5_SUPPORT__)
853 spc_L5ECALL_Status_Info_Callback(0xE4,0);
854 #else
855 spc_eCall_Handshake_Info_Notify(0xE4,0);
856 #endif
857 break;
858 default:
859 break;
860 }
861}
862
863void IvsReceiveHlack(const Ord8 data)
864{
865 MD_TRC_ECALL_IVS_DRV_HLACK((eCallModemIVS->CurMsd[0] & 0x0F), (data & 0x0F));
866 #if defined(__L5_SUPPORT__)
867 spc_L5ECALL_Status_Info_Callback(0xE3,data);
868 #else
869 spc_eCall_Handshake_Info_Notify(0xE3,data);
870 #endif
871
872 if ((eCallModemIVS->CurMsd[0] & 0x0F) == (data & 0x0F)) {
873 //eCallModemIVS->handler( eCALL_EVENT_RECV_HL_ACK_CORRECT, (void *)data); //NEED TO CHECK
874 } else {
875 //eCallModemIVS->handler( eCALL_EVENT_RECV_HL_ACK_MISMATCH, (void *)data);
876 }
877 IvsRxReset();
878 IvsTxReset(eCallModemIVS->CurMsd, ECALL_MSD_MAX_LENGTH);
879 eCallModemIVS->TxRx = KAL_FALSE;
880}
881
882void PsapCatchEvent(PsapEvent pe)
883{
884 MD_TRC_ECALL_PSAP_DRV_CATCH_EVENT(pe);
885
886 switch (pe) {
887 /* custom event handlers to be implemented here... */
888 /* see modemx.h for a list of possible events (enum PsapEvent) */
889 case PSAPEVENT_CONTROLLOCK:
890 eCallModemPSAP->TxRx = KAL_TRUE;
891 break;
892 case PSAPEVENT_IDLEPOSTHLACK:
893 PsapReset();
894 eCallModemPSAP->frameStartHlackCur = 0;
895 eCallModemPSAP->msdReceived = KAL_FALSE;
896 eCallModemPSAP->ivsPush = KAL_TRUE;
897 eCallModemPSAP->TxRx = KAL_FALSE;
898 break;
899 default:
900 break;
901 }
902}
903
904#endif
905
906#if defined(__ECALL_PSAP_SUPPORT__)
907
908/*------------------------------------------------*/
909/* The unit test code for PSAP. */
910/*------------------------------------------------*/
911
912void PsapReceiveMsd(const Ord8 *msd, int length) {
913 int n;
914
915 MD_TRC_ECALL_PSAP_DRV_RECEIVE_MSD();
916
917 for (n = 0; n < ECALL_MSD_MAX_LENGTH; n++) {
918 eCallModemPSAP->CurMsd[n] = msd[n];
919 }
920 eCallModemPSAP->msdReceived = KAL_TRUE;
921
922 for (n=0; n<20; n++) {
923 kal_uint32 base = 7*n;
924
925 MD_TRC_ECALL_PSAP_DRV_MSD_DATA(
926 msd[base], msd[base+1], msd[base+2], msd[base+3], msd[base+4], msd[base+5], msd[base+6]);
927 }
928
929 eCallModemPSAP->handler( eCALL_EVENT_PSAP_RECV_MSD, eCallModemPSAP->CurMsd);
930}
931
932//#pragma arm section code="SECONDARY_ROCODE"
933static void eCall_PSAP_hisr(void)
934{
935 kal_uint16 read_idx, write_idx;
936
937 read_idx = eCallModemPSAP->pcm_fifo_read;
938 write_idx = eCallModemPSAP->pcm_fifo_write;
939
940 if (eCallModemPSAP->pcm_fifo_read == eCallModemPSAP->next_to_process) {
941 // Processed data isn't enough
942 PCM4WAY_FillSE(0);
943 PCM4WAY_FillSpk(0);
944 } else {
945 // uplink-path
946 if (eCallModemPSAP->isUpdateUL[read_idx] == KAL_FALSE) {
947 PCM4WAY_PutToSE((const uint16*)(eCallModemPSAP->ul_pcm_input[read_idx]));
948
949 } else {
950 uint16 bufLen = SAL_PcmEx_GetBufLen(SAL_PCMEX_PNW_BUF_M2D_UL1);
951 if(ECALL_NB_BUF_LEN == bufLen) {
952 PCM4WAY_PutToSE((const uint16*)(eCallModemPSAP->ul_pcm_output_nb[read_idx]));
953
954 } else if(ECALL_WB_BUF_LEN == bufLen) {
955 PCM4WAY_PutToSE((const uint16*)(eCallModemPSAP->ul_pcm_output_wb[read_idx]));
956
957 } else {
958 PCM4WAY_PutToSE((const uint16*)(eCallModemPSAP->ul_pcm_output_swb[read_idx]));
959 }
960
961 eCallModemPSAP->isUpdateUL[read_idx] = KAL_FALSE;
962 MD_TRC_ECALL_PSAP_PCM_UPDATE_PUTTOSE(read_idx, bufLen);
963 }
964
965 // downlink-path no change
966 PCM4WAY_PutToSpk((const uint16*)(eCallModemPSAP->dl_pcm_input[read_idx]));
967
968 // Update index
969 eCallModemPSAP->pcm_fifo_write++;
970 if (eCallModemPSAP->pcm_fifo_write == 2*PCM_FIFO_LEN) {
971 eCallModemPSAP->pcm_fifo_write = 0;
972 }
973 }
974 if (read_idx != write_idx) {
975 // There is enough space to write data from microphone
976 eCallModemPSAP->ul_pcm_input_len[write_idx] = PCM4WAY_GetFromMic((uint16*)(eCallModemPSAP->ul_pcm_input[write_idx]));
977 eCallModemPSAP->dl_pcm_input_len[write_idx] = PCM4WAY_GetFromSD((uint16*)(eCallModemPSAP->dl_pcm_input[write_idx]));
978 MD_TRC_ECALL_PSAP_PCM_INPUT_LEN(write_idx, eCallModemPSAP->ul_pcm_input_len[write_idx], write_idx, eCallModemPSAP->dl_pcm_input_len);
979
980 // Update index
981 eCallModemPSAP->pcm_fifo_read++;
982 if (eCallModemPSAP->pcm_fifo_read == 2*PCM_FIFO_LEN) {
983 eCallModemPSAP->pcm_fifo_read = 0;
984 }
985 }
986
987 L1Audio_SetEvent(eCallModemPSAP->aud_id, (void*)0);
988}
989//#pragma arm section
990
991static void eCall_PSAP_ProcessFrame(void)
992{
993 kal_uint32 proc_idx = eCallModemPSAP->next_to_process;
994
995 // Here we only do DL downsample, UL upsample
996 kal_uint32 dl_ds_inLen, dl_ds_outLen;
997 kal_uint32 ul_us_inLen, ul_us_outLen;
998
999 kal_uint16 *p_dl_ds_inBuf, *p_dl_ds_outBuf;
1000 kal_uint16 *p_ul_us_inBuf, *p_ul_us_outBuf;
1001
1002 switch (eCallModemPSAP->mode) {
1003 case Psap:
1004 if (eCallModemPSAP->ivsPush == KAL_FALSE) {
1005 PsapSendStart();
1006 eCallModemPSAP->ivsPush = KAL_TRUE;
1007 }
1008 if (eCallModemPSAP->msdReceived == KAL_TRUE) {
1009 if ( ++eCallModemPSAP->frameStartHlackCur == eCallModemPSAP->frameStartHlack)
1010 PsapSendHlack(eCallModemPSAP->CurMsd[0] & 0x0F);
1011 }
1012
1013 /******************************************************
1014 * dl_pcm_input -> dl_pcm_fifo -> dl_pcm_output *
1015 * 32k 8k 32k *
1016 * [BAUDOT] -> [ECALLLIB] *
1017 ******************************************************/
1018
1019 /* [ECALL blisrc] DL downsample start */
1020 p_dl_ds_inBuf = eCallModemPSAP->dl_pcm_input[proc_idx];
1021 p_dl_ds_outBuf = eCallModemPSAP->dl_pcm_fifo[proc_idx];
1022
1023 if(ECALL_WB_BUF_LEN == eCallModemPSAP->dl_pcm_input_len[proc_idx]) {
1024 dl_ds_inLen = ECALL_WB_BUF_LEN << 1;
1025 dl_ds_outLen = ECALL_NB_BUF_LEN << 1;
1026 BLI_Convert(eCallModemPSAP->dl_downsample_16_8, (short *)p_dl_ds_inBuf, &dl_ds_inLen, (short *)p_dl_ds_outBuf, &dl_ds_outLen);
1027
1028 } else if(ECALL_SWB_BUF_LEN ==eCallModemPSAP->dl_pcm_input_len[proc_idx]) {
1029 dl_ds_inLen = ECALL_SWB_BUF_LEN << 1;
1030 dl_ds_outLen = ECALL_NB_BUF_LEN << 1;
1031 BLI_Convert(eCallModemPSAP->dl_downsample_32_8, (short *)p_dl_ds_inBuf, &dl_ds_inLen, (short *)p_dl_ds_outBuf, &dl_ds_outLen);
1032
1033 } else{
1034 memcpy(p_dl_ds_outBuf, p_dl_ds_inBuf, ECALL_NB_BUF_LEN << 1);
1035 }
1036 /* [ECALL blisrc] DL downsample end */
1037
1038 PsapProcess( (Int16 *)eCallModemPSAP->dl_pcm_fifo[proc_idx]);
1039
1040 if (eCallModemPSAP->TxRx) {
1041 memcpy(eCallModemPSAP->ul_pcm_fifo[proc_idx], eCallModemPSAP->dl_pcm_fifo[proc_idx], ECALL_NB_BUF_LEN*sizeof(kal_uint16));
1042
1043 /*****************************************************
1044 * dl_pcm_output <- dl_pcm_fifo <- dl_pcm_input *
1045 * 32k 8k 32k *
1046 * [ECALLLIB] <- [BAUDOT] *
1047 *****************************************************/
1048
1049 /* [ECALL blisrc] UL up sampling start */
1050 //NB output
1051 p_ul_us_inBuf = eCallModemPSAP->ul_pcm_fifo[proc_idx];
1052 p_ul_us_outBuf = eCallModemPSAP->ul_pcm_output_nb[proc_idx];
1053 memcpy(p_ul_us_outBuf, p_ul_us_inBuf, ECALL_NB_BUF_LEN << 1);
1054
1055 //WB output
1056 ul_us_inLen = ECALL_NB_BUF_LEN << 1;
1057 ul_us_outLen = ECALL_WB_BUF_LEN << 1;
1058 p_ul_us_outBuf = eCallModemPSAP->ul_pcm_output_wb[proc_idx];
1059 BLI_Convert(eCallModemPSAP->ul_upsample_8_16, (short *)p_ul_us_inBuf, &ul_us_inLen, (short *)p_ul_us_outBuf, &ul_us_outLen);
1060
1061 //SWB output
1062 ul_us_inLen = ECALL_NB_BUF_LEN << 1;
1063 ul_us_outLen = ECALL_SWB_BUF_LEN << 1;
1064 p_ul_us_outBuf = eCallModemPSAP->ul_pcm_output_swb[proc_idx];
1065 BLI_Convert(eCallModemPSAP->ul_upsample_8_32, (short *)p_ul_us_inBuf, &ul_us_inLen, (short *)p_ul_us_outBuf, &ul_us_outLen);
1066 /* [ECALL blisrc] UL up sampling end */
1067
1068 eCallModemPSAP->isUpdateUL[proc_idx] = KAL_TRUE;
1069 MD_TRC_ECALL_PSAP_PCM_UPDATE_UL(proc_idx, eCallModemPSAP->TxRx, proc_idx, eCallModemPSAP->isUpdateUL[proc_idx]);
1070 }
1071
1072 break;
1073 case PsapRx:
1074 if (eCallModemPSAP->ivsPush == KAL_FALSE) {
1075 PsapSendStart();
1076 eCallModemPSAP->ivsPush = KAL_TRUE;
1077 }
1078 if (eCallModemPSAP->msdReceived == KAL_TRUE) {
1079 if ( ++eCallModemPSAP->frameStartHlackCur == eCallModemPSAP->frameStartHlack)
1080 PsapSendHlack(eCallModemPSAP->CurMsd[0] & 0x0F);
1081 }
1082
1083 /******************************************************
1084 * dl_pcm_input -> dl_pcm_fifo -> dl_pcm_output *
1085 * 32k 8k 32k *
1086 * [BAUDOT] -> [ECALLLIB] *
1087 ******************************************************/
1088
1089 /* [ECALL blisrc] DL downsample start */
1090 p_dl_ds_inBuf = eCallModemPSAP->dl_pcm_input[proc_idx];
1091 p_dl_ds_outBuf = eCallModemPSAP->dl_pcm_fifo[proc_idx];
1092
1093 if(ECALL_WB_BUF_LEN == eCallModemPSAP->dl_pcm_input_len[proc_idx]) {
1094 dl_ds_inLen = ECALL_WB_BUF_LEN << 1;
1095 dl_ds_outLen = ECALL_NB_BUF_LEN << 1;
1096 BLI_Convert(eCallModemPSAP->dl_downsample_16_8, (short *)p_dl_ds_inBuf, &dl_ds_inLen, (short *)p_dl_ds_outBuf, &dl_ds_outLen);
1097
1098 } else if(ECALL_SWB_BUF_LEN ==eCallModemPSAP->dl_pcm_input_len[proc_idx]) {
1099 dl_ds_inLen = ECALL_SWB_BUF_LEN << 1;
1100 dl_ds_outLen = ECALL_NB_BUF_LEN << 1;
1101 BLI_Convert(eCallModemPSAP->dl_downsample_32_8, (short *)p_dl_ds_inBuf, &dl_ds_inLen, (short *)p_dl_ds_outBuf, &dl_ds_outLen);
1102
1103 } else{
1104 memcpy(p_dl_ds_outBuf, p_dl_ds_inBuf, ECALL_NB_BUF_LEN << 1);
1105 }
1106 /* [ECALL blisrc] DL downsample end */
1107
1108 PsapRxProcess( (Int16 *)eCallModemPSAP->dl_pcm_fifo[proc_idx] );
1109
1110 if (eCallModemPSAP->TxRx) {
1111 memcpy(eCallModemPSAP->ul_pcm_fifo[proc_idx], eCallModemPSAP->dl_pcm_fifo[proc_idx], ECALL_NB_BUF_LEN*sizeof(kal_uint16));
1112
1113 /*****************************************************
1114 * dl_pcm_output <- dl_pcm_fifo <- dl_pcm_input *
1115 * 32k 8k 32k *
1116 * [ECALLLIB] <- [BAUDOT] *
1117 *****************************************************/
1118
1119 /* [ECALL blisrc] UL up sampling start */
1120 //NB output
1121 p_ul_us_inBuf = eCallModemPSAP->ul_pcm_fifo[proc_idx];
1122 p_ul_us_outBuf = eCallModemPSAP->ul_pcm_output_nb[proc_idx];
1123 memcpy(p_ul_us_outBuf, p_ul_us_inBuf, ECALL_NB_BUF_LEN << 1);
1124
1125 //WB output
1126 ul_us_inLen = ECALL_NB_BUF_LEN << 1;
1127 ul_us_outLen = ECALL_WB_BUF_LEN << 1;
1128 p_ul_us_outBuf = eCallModemPSAP->ul_pcm_output_wb[proc_idx];
1129 BLI_Convert(eCallModemPSAP->ul_upsample_8_16, (short *)p_ul_us_inBuf, &ul_us_inLen, (short *)p_ul_us_outBuf, &ul_us_outLen);
1130
1131 //SWB output
1132 ul_us_inLen = ECALL_NB_BUF_LEN << 1;
1133 ul_us_outLen = ECALL_SWB_BUF_LEN << 1;
1134 p_ul_us_outBuf = eCallModemPSAP->ul_pcm_output_swb[proc_idx];
1135 BLI_Convert(eCallModemPSAP->ul_upsample_8_32, (short *)p_ul_us_inBuf, &ul_us_inLen, (short *)p_ul_us_outBuf, &ul_us_outLen);
1136 /* [ECALL blisrc] UL up sampling end */
1137
1138 eCallModemPSAP->isUpdateUL[proc_idx] = KAL_TRUE;
1139 MD_TRC_ECALL_PSAP_PCM_UPDATE_UL(proc_idx, eCallModemPSAP->TxRx, proc_idx, eCallModemPSAP->isUpdateUL[proc_idx]);
1140 }
1141
1142 break;
1143 default:
1144 ASSERT(0);
1145 break;
1146 }
1147}
1148
1149static void eCall_PSAP_ProcessTask(void *data)
1150{
1151 if (eCallModemPSAP == NULL) {
1152 return;
1153 }
1154
1155 while (eCallModemPSAP->next_to_process != eCallModemPSAP->pcm_fifo_write) {
1156 // Process each frame
1157 eCall_PSAP_ProcessFrame();
1158
1159 // Update index
1160 eCallModemPSAP->next_to_process++;
1161 if (eCallModemPSAP->next_to_process == 2 * PCM_FIFO_LEN) {
1162 eCallModemPSAP->next_to_process = 0;
1163 }
1164 }
1165}
1166
1167static void eCall_PSAP_OnHandler( void *data )
1168{
1169 (void)data;
1170
1171 PCM4WAY_Start(eCall_PSAP_hisr, 0);
1172}
1173
1174static void eCall_PSAP_OffHandler( void *data )
1175{
1176 (void)data;
1177
1178 PCM4WAY_Stop(0);
1179}
1180
1181eCall_Modem_Status eCall_PSAP_Open(eCall_Callback handler)
1182{
1183 ASSERT( handler != NULL );
1184
1185 if ( eCallModemIVS != NULL ) {
1186 return eCALL_OPERATION_FAIL;
1187 }
1188
1189 if ( eCallModemPSAP != NULL ) {
1190 return eCALL_OPERATION_ALREADY_OPEN;
1191 }
1192
1193 //L1SP_EnableSpeechEnhancement(KAL_FALSE);
1194
1195 //eCallModemPSAP = (EcallShell *)audio_alloc_mem_cacheable( sizeof(EcallShell) );
1196 eCallModemPSAP = (EcallShell *)get_ctrl_buffer( sizeof(EcallShell) );
1197 ASSERT( eCallModemPSAP != NULL );
1198 memset(eCallModemPSAP, 0, sizeof(EcallShell));
1199
1200 // Allocate for PSAP internal structure
1201 {
1202 kal_uint32 reqSize;
1203
1204 reqSize = (kal_uint32) PsapGetMemSize();
1205 //eCallModemPSAP->allocMem = (void *)audio_alloc_mem_cacheable( reqSize );
1206 eCallModemPSAP->allocMem = (void *)get_ctrl_buffer( reqSize );
1207 memset(eCallModemPSAP->allocMem, 0, sizeof(reqSize));
1208 PsapInit( eCallModemPSAP->allocMem );
1209 }
1210
1211 // open BLI Src for ecall
1212 // 32k <-> 8k
1213 eCallModemPSAP->dl_downsample_32_8 = BLI_Open(32000, 1, 8000, 1, (signed char*)eCallModemPSAP->internal_buf_dl_in, 0); // open DL down sampling src
1214 eCallModemPSAP->ul_upsample_8_32 = BLI_Open(8000, 1, 32000, 1, (signed char*)eCallModemPSAP->internal_buf_ul_out, 0); // open UL up sampling src
1215 // 16k <-> 8k
1216 eCallModemPSAP->dl_downsample_16_8 = BLI_Open(16000, 1, 8000, 1, (signed char*)eCallModemPSAP->internal_buf_dl_in2, 0); // open DL down sampling src
1217 eCallModemPSAP->ul_upsample_8_16 = BLI_Open(8000, 1, 16000, 1, (signed char*)eCallModemPSAP->internal_buf_ul_out2, 0); // open UL up sampling src
1218
1219 eCallModemPSAP->aud_id = L1Audio_GetAudioID();
1220 L1Audio_SetEventHandler(eCallModemPSAP->aud_id , eCall_PSAP_ProcessTask);
1221 L1Audio_SetFlag(eCallModemPSAP->aud_id);
1222
1223 PsapReset();
1224
1225 eCallModemPSAP->mode = Psap; //PsapRx;
1226 eCallModemPSAP->ivsPush = KAL_TRUE; //KAL_FALSE;
1227 eCallModemPSAP->msdReceived = KAL_FALSE;
1228 eCallModemPSAP->frameStartHlack = 10;
1229 eCallModemPSAP->pcm_fifo_read = 0;
1230 eCallModemPSAP->pcm_fifo_write = PCM_FIFO_LEN;
1231 eCallModemPSAP->next_to_process = PCM_FIFO_LEN;
1232 eCallModemPSAP->frameStartHlackCur = 0;
1233 eCallModemPSAP->handler = handler;
1234
1235 for (int i=0; i<2*PCM_FIFO_LEN; i++) {
1236 eCallModemPSAP->isUpdateUL[i] = KAL_FALSE;
1237 }
1238
1239 if ( AM_IsSpeechOn() ) {
1240 eCall_PSAP_OnHandler( (void *)0 );
1241 }
1242
1243 // Hook service to L1SP
1244 L1SP_Register_Pcm4WayService( eCall_PSAP_OnHandler, eCall_PSAP_OffHandler );
1245
1246 return eCALL_OPERATION_SUCCESS;
1247}
1248
1249eCall_Modem_Status eCall_PSAP_Close(void)
1250{
1251 if( eCallModemPSAP == NULL ) {
1252 return eCALL_OPERATION_ALREADY_CLOSE;
1253 }
1254
1255 if ( eCallModemIVS != NULL ) {
1256 return eCALL_OPERATION_FAIL;
1257 }
1258
1259 // Unhook service to L1SP
1260 L1SP_UnRegister_Pcm4Way_Service();
1261
1262 if ( AM_IsSpeechOn() ) {
1263 eCall_PSAP_OffHandler( (void *)0 );
1264 }
1265
1266 L1Audio_ClearFlag(eCallModemPSAP->aud_id);
1267 L1Audio_FreeAudioID(eCallModemPSAP->aud_id);
1268
1269 BLI_Close(eCallModemPSAP->dl_downsample_16_8, 0); // Close DL down sampling src
1270 BLI_Close(eCallModemPSAP->dl_downsample_32_8, 0); // Close DL down sampling src
1271 BLI_Close(eCallModemPSAP->ul_upsample_8_16, 0); // Close UL up sampling src
1272 BLI_Close(eCallModemPSAP->ul_upsample_8_32, 0); // Close UL up sampling src
1273
1274 // Deallocate for PSAP internal structure
1275 {
1276 PsapDeinit();
1277 free_ctrl_buffer( (void *) eCallModemPSAP->allocMem );
1278 }
1279
1280 free_ctrl_buffer( (void *) eCallModemPSAP );
1281 //L1SP_EnableSpeechEnhancement(KAL_TRUE);
1282 eCallModemPSAP = NULL;
1283
1284 return eCALL_OPERATION_SUCCESS;
1285}
1286
1287eCall_Modem_Status eCall_PSAP_SendStart(void)
1288{
1289 if (eCallModemPSAP == NULL) {
1290 return eCALL_OPERATION_FAIL;
1291 }
1292
1293 if ( eCallModemIVS != NULL ) {
1294 return eCALL_OPERATION_FAIL;
1295 }
1296
1297 eCallModemPSAP->TxRx = KAL_TRUE;
1298 eCallModemPSAP->mode = Psap;
1299 eCallModemPSAP->ivsPush = KAL_FALSE;
1300
1301 return eCALL_OPERATION_SUCCESS;
1302}
1303
1304#else
1305
1306// Provide dummy function to support feature switchable
1307void PsapReceiveMsd(const Ord8 *msd, int length) { }
1308eCall_Modem_Status eCall_PSAP_Open(eCall_Callback handler) {return eCALL_OPERATION_FAIL;}
1309eCall_Modem_Status eCall_PSAP_Close(void) {return eCALL_OPERATION_FAIL;}
1310eCall_Modem_Status eCall_PSAP_SendStart(void) {return eCALL_OPERATION_FAIL;}
1311
1312#endif