diff gsm-fw/services/etm/etm_audio.c @ 164:d78219c43fbf

gsm-fw/services/etm: initial import from the Leonardo semi-src
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Mon, 18 Nov 2013 06:39:44 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/services/etm/etm_audio.c	Mon Nov 18 06:39:44 2013 +0000
@@ -0,0 +1,401 @@
+/********************************************************************************
+ * Enhanced TestMode (ETM)
+ * @file	etm_audio.c (Support for AUDIO commands)
+ *
+ * @author	Kim T. Peteren (ktp@ti.com)
+ * @version 0.8
+ *
+
+ *
+ * History:
+ *
+ * 	Date       	Modification
+ *  ------------------------------------
+ *  16/06/2003	Creation
+ *  30/06/2003  Small cleanup in func. etm_audio_write, etm_audio_saveload and
+ *              etm_aud_wait_for_aud_event is updated and renamed
+ *  12/08/2003  The func. etm_audio_write has been updated regarding the AEC struct.
+ *  14/08/2003  The func. etm_audio_read has been updated regarding the AEC struct.
+ *  17/03/2004  Modified the event handling, events revceived from the Audio SWE. 
+ *              Integrated event callback function, etm_audio_callback().
+ *
+ * (C) Copyright 2003 by Texas Instruments Incorporated, All Rights Reserved
+ *********************************************************************************/
+
+
+#include "etm/etm.h"
+#include "etm/etm_api.h"
+#include "etm/etm_trace.h"
+#include "etm/etm_env.h" // Need because use of T_ETM_ENV_CTRL_BLK 
+#include "etm/etm_audio_err.h" // Privat Audio error codes for PC and Target 
+
+#include "etm/etm_trace.h"
+#include "audio/audio_api.h"
+
+#include "rv/rv_general.h"
+#include "spi/spi_drv.h" // used for codec read/write
+
+#include "memif/mem.h"
+#include <string.h>
+
+
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+
+// Version of the ETM AUDIO module
+//const uint16 etm_audio_revision = (1<<12) | (0x1);
+
+extern T_ETM_ENV_CTRL_BLK *etm_env_ctrl_blk;
+
+static int etm_audio_event_status = 0;
+
+
+/******************************************************************************
+ * Internal prototypes 
+ *****************************************************************************/
+
+int etm_audio(uint8 *indata, int insize);
+T_RV_HDR *etm_audio_wait_for_event(UINT16 msg_id_expected);
+T_ETM_PKT *etm_audio_setup(uint8 fid, uint8 cfg_data);
+void etm_audio_callback(void *event_from_audio);
+
+
+/******************************************************************************
+ * Register the Audio Module to the ETM database 
+ *****************************************************************************/
+
+int etm_audio_init(void)
+{
+    int result; 
+
+    result = etm_register("AUDIO", ETM_AUDIO, 0, 0, etm_audio);
+    return result;    
+}
+
+
+/******************************************************************************
+ * Audio Full Access Read Function
+ *****************************************************************************/
+
+int etm_audio_read(T_ETM_PKT *pkt, uint8 *buf)
+{
+    int result, size = 0, size_tmp, i;
+    uint8 param;
+    T_AUDIO_FULL_ACCESS_READ audio;
+    T_AUDIO_AEC_CFG *aec_parameter = NULL;
+    void *parameter = NULL;
+    
+    param = *buf;
+    if ((result = etm_pkt_put8(pkt, param)) < 0) 
+        return result;
+
+    tr_etm(TgTrAudio, "ETM AUDIO: _audio_read: param(%d)", param);
+   
+    audio.variable_indentifier = param;
+    audio.data = (T_AUDIO_FULL_ACCESS_READ *) &pkt->data[2]; //data[0] = fid
+                                                             //data[1] = parameter/identifier
+    
+    if ((result = audio_full_access_read(&audio)) != AUDIO_OK){
+        tr_etm(TgTrAudio, "ETM AUDIO: _audio_read: ERROR(%d)", result);
+        if (result == AUDIO_ERROR) 
+            return ETM_INVAL;         // Invalid audio parameter
+        else
+            return ETM_AUDIO_FATAL;
+    }
+
+    switch (param) {
+    case AUDIO_PATH_USED:
+        size = sizeof(T_AUDIO_VOICE_PATH_SETTING);
+        break;
+    case AUDIO_MICROPHONE_MODE:
+    case AUDIO_MICROPHONE_GAIN:
+    case AUDIO_MICROPHONE_EXTRA_GAIN:
+    case AUDIO_MICROPHONE_OUTPUT_BIAS:
+    case AUDIO_MICROPHONE_SPEAKER_LOOP_SIDETONE:
+        size = sizeof(INT8);                         
+        break;
+    case AUDIO_MICROPHONE_SPEAKER_LOOP_AEC:
+        size = sizeof(T_AUDIO_AEC_CFG);              
+      
+        aec_parameter = (T_AUDIO_AEC_CFG *) &pkt->data[2];
+
+        etm_pkt_put16(pkt, aec_parameter->aec_enable);                  // 1
+#if (L1_NEW_AEC)
+        etm_pkt_put16(pkt, aec_parameter->continuous_filtering);        // 2
+        etm_pkt_put16(pkt, aec_parameter->granularity_attenuation);     // 3
+        etm_pkt_put16(pkt, aec_parameter->smoothing_coefficient);       // 4
+        etm_pkt_put16(pkt, aec_parameter->max_echo_suppression_level);  // 5
+        etm_pkt_put16(pkt, aec_parameter->vad_factor);                  // 6
+        etm_pkt_put16(pkt, aec_parameter->absolute_threshold);          // 7
+        etm_pkt_put16(pkt, aec_parameter->factor_asd_filtering);        // 8
+        etm_pkt_put16(pkt, aec_parameter->factor_asd_muting);           // 9
+        etm_pkt_put16(pkt, aec_parameter->aec_visibility);              //10
+#else
+        etm_pkt_put16(pkt, aec_parameter->aec_mode);                    // 2
+        etm_pkt_put16(pkt, aec_parameter->echo_suppression_level);      // 3
+#endif // end of (L1_NEW_AEC)
+        etm_pkt_put16(pkt, aec_parameter->noise_suppression_enable);    // 4 or 11
+        etm_pkt_put16(pkt, aec_parameter->noise_suppression_level);     // 5 or 12
+        break;
+    case AUDIO_MICROPHONE_FIR:
+    case AUDIO_SPEAKER_FIR:
+        size = sizeof(T_AUDIO_FIR_COEF);             
+        break;
+    case AUDIO_SPEAKER_MODE:
+    case AUDIO_SPEAKER_GAIN:
+    case AUDIO_SPEAKER_FILTER:
+    case AUDIO_SPEAKER_BUZZER_STATE:
+        size = sizeof(INT8);                         
+        break;
+    case AUDIO_SPEAKER_VOLUME_LEVEL:
+        size = sizeof(T_AUDIO_SPEAKER_LEVEL);        
+        break;
+    default:
+        size = ETM_INVAL;                            
+    }
+
+    pkt->size += size;
+    return ETM_OK;
+}
+
+ 
+/******************************************************************************
+ * Audio Full Access Write Function
+ *****************************************************************************/
+
+int etm_audio_write(T_ETM_PKT *pkt, uint8 *buf)
+{
+    T_RV_HDR *msg = NULL;
+    T_RV_RETURN return_path;
+    T_AUDIO_FULL_ACCESS_WRITE audio;
+    T_AUDIO_AEC_CFG *aec_parameter = NULL;
+    void *parameter = NULL;
+    int result = ETM_OK, i;
+    uint8 param;
+
+    param = *buf++;
+    if ((result = etm_pkt_put8(pkt, param)) < ETM_OK) {
+        return result;
+    } 
+
+    tr_etm(TgTrAudio, "ETM AUDIO: _audio_write: param(%d)", param);
+
+    return_path.addr_id        = NULL; //etm_env_ctrl_blk->addr_id;
+    return_path.callback_func  = etm_audio_callback;
+
+    audio.variable_indentifier = param;
+    audio.data = buf;
+
+    switch (param) {
+    case AUDIO_MICROPHONE_SPEAKER_LOOP_AEC:
+        tr_etm(TgTrAudio, "ETM AUDIO: _audio_write: AUDIO_MICROPHONE_SPEAKER_LOOP_AEC"); // RemoveMe
+        aec_parameter = etm_malloc (sizeof(T_AUDIO_AEC_CFG));
+        
+        aec_parameter->aec_enable =                 etm_get16(buf); buf += 2;// 1
+#if (L1_NEW_AEC)
+        if (etm_get16(buf))  // 2
+            aec_parameter->continuous_filtering = TRUE;
+         else
+            aec_parameter->continuous_filtering = FALSE;
+        buf += 2;
+        aec_parameter->granularity_attenuation =    etm_get16(buf); buf += 2;// 3
+        aec_parameter->smoothing_coefficient =      etm_get16(buf); buf += 2;// 4
+        aec_parameter->max_echo_suppression_level = etm_get16(buf); buf += 2;// 5
+        aec_parameter->vad_factor =                 etm_get16(buf); buf += 2;// 6
+        aec_parameter->absolute_threshold =         etm_get16(buf); buf += 2;// 7
+        aec_parameter->factor_asd_filtering =       etm_get16(buf); buf += 2;// 8
+        aec_parameter->factor_asd_muting =          etm_get16(buf); buf += 2;// 9
+        aec_parameter->aec_visibility =             etm_get16(buf); buf += 2;// 10
+#else
+        aec_parameter->aec_mode =                   etm_get16(buf); buf += 2;// 2
+        aec_parameter->echo_suppression_level =     etm_get16(buf); buf += 2;// 3
+#endif // end of (L1_NEW_AEC)
+#if (L1_ANR == 0)
+        aec_parameter->noise_suppression_enable =   etm_get16(buf); buf += 2;// 4 or 11
+        aec_parameter->noise_suppression_level =    etm_get16(buf); // 5 or 12
+#endif // end of (L1_ANR)
+        audio.data = aec_parameter;
+        break;
+    case AUDIO_MICROPHONE_FIR:
+    case AUDIO_SPEAKER_FIR:
+        tr_etm(TgTrAudio, "ETM AUDIO: _audio_write: AUDIO_MICROPHONE/SPEAKER_FIR [%d]", 
+               sizeof(T_AUDIO_FIR_COEF)/2); // RemoveMe
+
+        parameter = etm_malloc (sizeof(T_AUDIO_FIR_COEF));
+        // Write coeffient values
+        for (i=0; i <= (sizeof(T_AUDIO_FIR_COEF)/2); i++) {
+            ((T_AUDIO_FIR_COEF *) parameter)->coefficient[i]  = etm_get16(buf);  buf += 2;
+        }
+        audio.data = parameter;
+        break;
+    }
+
+    if ((result = audio_full_access_write(&audio, return_path)) != AUDIO_OK) {
+        tr_etm(TgTrAudio, "ETM AUDIO: _audio_write: ERROR(%d)", result);
+        if (result == AUDIO_ERROR) 
+            result = ETM_INVAL;         // Invalid audio parameter
+        else
+            result = ETM_AUDIO_FATAL;
+    }
+
+    // Wait for recv. of event: AUDIO_FULL_ACCESS_WRITE_DONE
+    rvf_wait(0xffff, 100); // Timeout 100 ticks
+    tr_etm(TgTrAudio, "ETM AUDIO: _audio_write: STATUS(%d)", etm_audio_event_status);
+
+    if (parameter != NULL) {
+        etm_free(parameter);
+        parameter = NULL;
+    }
+
+    if (aec_parameter != NULL) {
+        etm_free(aec_parameter);    
+        aec_parameter = NULL;
+    }
+
+    if (etm_audio_event_status != 0) {
+        etm_audio_event_status = 0;
+        result = ETM_AUDIO_FATAL;
+    }
+
+    return result;
+}
+
+/******************************************************************************
+ * Audio Save and Load cfg file Function
+ *****************************************************************************/
+
+int etm_audio_saveload(T_ETM_PKT *pkt, uint8 saveload, void *buf, int size)
+{
+    T_RV_HDR *msg;
+    T_AUDIO_MODE_SAVE audio_s;
+    T_AUDIO_MODE_LOAD audio_l;
+    T_RV_RETURN return_path;
+    int result = ETM_OK; 
+    int error, event;
+    
+    return_path.addr_id        = etm_env_ctrl_blk->addr_id;
+    return_path.callback_func  = NULL;
+
+    switch(saveload) {
+    case 'S':
+        memcpy(audio_s.audio_mode_filename, buf, size);
+        result = audio_mode_save(&audio_s, return_path); 
+        break;
+    case 'L':
+        memcpy(audio_l.audio_mode_filename, buf, size);
+        result = audio_mode_load(&audio_l, return_path); 
+        break;
+    default:
+        tr_etm(TgTrAudio, "ETM AUDIO: _audio_saveload: FAILED"); 
+        break;
+    }
+    
+    rvf_wait(0xffff, 100); // Timeout 100 ticks
+    tr_etm(TgTrAudio, "ETM AUDIO: _audio_saveload: STATUS(%d)", etm_audio_event_status);
+
+    if (etm_audio_event_status != 0) {
+        etm_audio_event_status = 0;
+        return ETM_AUDIO_FATAL;
+    }
+
+    if (result != AUDIO_OK)
+        return ETM_AUDIO_FATAL;
+
+    return result;
+}
+
+
+/******************************************************************************
+ * ETM AUDIO callback functio
+ *****************************************************************************/
+
+void etm_audio_callback(void *event_from_audio)
+{
+    tr_etm(TgTrEtmLow,"ETM: AUDIO: _audio_callback: recv. event (0x%x)", 
+           ((T_RV_HDR *) event_from_audio)->msg_id);
+    
+    switch (((T_RV_HDR *) event_from_audio)->msg_id)
+    {
+    case AUDIO_FULL_ACCESS_WRITE_DONE:
+        tr_etm(TgTrAudio, "ETM AUDIO: _audio_callback: recv. event AUDIO_FULL_ACCESS_WRITE_DONE");
+        etm_audio_event_status = ((T_AUDIO_FULL_ACCESS_WRITE_DONE *) event_from_audio)->status;
+        break;
+    case AUDIO_MODE_SAVE_DONE:
+        tr_etm(TgTrAudio, "ETM AUDIO: _audio_callback: recv. event AUDIO_MODE_SAVE_DONE");
+        etm_audio_event_status = ((T_AUDIO_SAVE_DONE *) event_from_audio)->status;
+        break;
+    case AUDIO_MODE_LOAD_DONE:
+        tr_etm(TgTrAudio, "ETM AUDIO: _audio_callback: recv. event AUDIO_MODE_LOAD_DONE");
+        etm_audio_event_status = ((T_AUDIO_LOAD_DONE *) event_from_audio)->status;
+        break;
+    }
+    
+    if (event_from_audio != NULL) {
+//        etm_free(event_from_audio); 
+        event_from_audio = NULL;
+    }
+}
+
+
+/******************************************************************************
+ * ETM AUDIO Moudle - Main Task
+ *****************************************************************************/
+
+// AUDIO packet structure for audio read/write and codec read/write: 
+// |fid(8)|param(8)|--data(W)--| and for audio save/load |fid|--data(W)--|
+
+int etm_audio(uint8 *indata, int insize)
+{
+    int error = ETM_OK;
+    uint8 fid;
+    T_ETM_PKT *pkt = NULL;  
+
+    fid = *indata++;   
+       
+    tr_etm(TgTrAudio, "ETM AUDIO: _audio: fid(%c) param(%d) recv. size(%d)", 
+           fid, *indata, insize); 
+
+    /* Create TestMode return Packet */
+    if ((pkt = (T_ETM_PKT *) etm_malloc(sizeof(T_ETM_PKT))) == NULL) {
+        return ETM_NOMEM;
+    }
+    
+    // Init. of return packet
+    pkt->mid     = ETM_AUDIO;
+    pkt->status  = ETM_OK;
+    pkt->size    = 0;
+    pkt->index   = 0;
+    etm_pkt_put8(pkt, fid);
+    
+    if (error == ETM_OK) {
+        switch (fid) {
+        case 'R':
+            error = etm_audio_read(pkt, indata);                  
+            break;
+        case 'W':
+            error = etm_audio_write(pkt, indata); 
+            break;
+        case 'S':
+        case 'L': 
+            error = etm_audio_saveload(pkt, fid, indata, insize);  
+            break;
+        default:
+            tr_etm(TgTrAudio, "ETM AUDIO: _audio: fid(%c) - ERROR ", fid);
+            error = ETM_NOSYS;                                
+            break;
+        }
+    }
+    
+    if (error < 0) {
+        tr_etm(TgTrAudio,"ETM AUDIO: _audio: ERROR(%d)", error); 
+        pkt->status = -error;
+
+    }
+
+    etm_pkt_send(pkt);
+    etm_free(pkt);
+
+    return ETM_OK;
+}
+