[Feature][Modem]Update MTK MODEM V1.6 baseline version: MOLY.NR15.R3.MD700.IVT.MP1MR3.MP.V1.6

MTK modem version: MT2735_IVT_MOLY.NR15.R3.MD700.IVT.MP1MR3.MP.V1.6.tar.gz
RF  modem version: NA

Change-Id: I45a4c2752fa9d1a618beacd5d40737fb39ab64fb
diff --git a/mcu/driver/drv/include/BC_drv.h b/mcu/driver/drv/include/BC_drv.h
new file mode 100644
index 0000000..3fe7047
--- /dev/null
+++ b/mcu/driver/drv/include/BC_drv.h
@@ -0,0 +1,98 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    BC_drv.h
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   Driver 0f Bit Copy.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+ 
+ 
+#ifndef __BC_DRV_H__
+#define __BC_DRV_H__
+
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+#include "drv_comm.h"
+#include "reg_base.h"
+#include "drv_features.h"
+
+#if defined (__3G_F8F9BC_HW_DRV_V1__)
+
+#define BC_REG_STA      (BITCP_base + 0x0000)
+#define BC_REG_SRC      (BITCP_base + 0x0004)
+#define BC_REG_DST      (BITCP_base + 0x0008)
+#define BC_REG_LDST     (BITCP_base + 0x000c)
+#define BC_REG_SIZE     (BITCP_base + 0x0010)
+#define BC_REG_CON      (BITCP_base + 0x0014)
+#define BC_REG_START    (BITCP_base + 0x0018)
+
+void BitCopy(const kal_uint8 *src, kal_uint16 srcOffset, kal_uint8 *dest, kal_uint16 *destOffset, kal_uint16 length);
+
+#endif   /* __3G_F8F9BC_HW_DRV_V1__ */
+
+#endif
diff --git a/mcu/driver/drv/include/cdl.h b/mcu/driver/drv/include/cdl.h
new file mode 100644
index 0000000..69d1b10
--- /dev/null
+++ b/mcu/driver/drv/include/cdl.h
@@ -0,0 +1,80 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    cdl.h
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   This file is to trigger card download
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#ifndef _CDL_H_
+#define _CDL_H_
+
+#ifdef __CARD_DOWNLOAD__
+
+extern void CDL_StartCardDownload(void);
+extern void CDL_FullDownloadTest(void);
+
+#endif /* __CARD_DOWNLOAD__ */
+
+#endif /* _CDL_H_ */
+
diff --git a/mcu/driver/drv/include/drv_trc.h b/mcu/driver/drv/include/drv_trc.h
new file mode 100644
index 0000000..94feb12
--- /dev/null
+++ b/mcu/driver/drv/include/drv_trc.h
@@ -0,0 +1,411 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+/*******************************************************************************
+ * Filename:
+ * ---------
+ *   bmt_trc.h
+ *
+ * Project:
+ * --------
+ *   MAUI
+ *
+ * Description:
+ * ------------
+ *   This is trace map definition for BMT.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#ifndef _DRV_TRC_H
+#define _DRV_TRC_H
+#ifndef GEN_FOR_PC
+   #ifndef _STACK_CONFIG_H
+   #error "stack_config.h should be included before tst_config.h"
+   #endif
+#else
+   #include "kal_trace.h"
+#endif /* GEN_FOR_PC */
+/*add by RHR suggest Add*/ 
+#include "kal_public_defs.h" //MSBB change #include "stack_config.h"
+#include "kal_trace.h"
+/*add by RHR suggest Add*/ 
+#ifndef _KAL_TRACE_H
+   #error "kal_trace.h should be included before tst_trace.h"
+#endif
+#if !defined(GEN_FOR_PC)
+#if defined(__TST_MODULE__) || defined(__CUSTOM_RELEASE__)
+#endif /* TST Trace Defintion */
+#endif
+#if !defined(GEN_FOR_PC)
+#include"drv_trc_mod_rtc_hisr_utmd.h"
+#endif
+#if !defined(GEN_FOR_PC)
+#include"drv_trc_mod_msdc_hisr_utmd.h"
+#endif
+#if !defined(GEN_FOR_PC)
+#include"drv_trc_mod_ppp_hw_utmd.h"
+#endif
+#if !defined(GEN_FOR_PC)
+#include"drv_trc_mod_uart_1_hisr_utmd.h"
+#endif
+#if ((defined(__ACCDET_SUPPORT__)||defined(__ACCDET_HYBRID_SOLUTION_SUPPORT__)) && !defined(__L1_STANDALONE__))
+#if !defined(GEN_FOR_PC)
+#include"drv_trc_mod_aux_utmd.h"
+#endif
+#endif //#if defined(__ACCDET_SUPPORT__)
+#ifdef ISP_SUPPORT
+#if !defined(GEN_FOR_PC)
+#include"drv_trc_mod_cal_utmd.h"
+#endif
+#endif
+#endif /* _DRV_TRC_H */
diff --git a/mcu/driver/drv/include/drv_trc_mod_aux_utmd.json b/mcu/driver/drv/include/drv_trc_mod_aux_utmd.json
new file mode 100644
index 0000000..2e98b02
--- /dev/null
+++ b/mcu/driver/drv/include/drv_trc_mod_aux_utmd.json
@@ -0,0 +1,378 @@
+{
+  "legacyParameters": {}, 
+  "module": "MOD_AUX", 
+  "traceClassDefs": [
+    {
+      "TRACE_INFO": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_WARNING": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_ERROR": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_FUNC": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_STATE": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_1": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_2": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_3": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_4": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_5": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_6": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_7": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_8": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_9": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_10": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }
+  ], 
+  "traceDefs": [
+    {
+      "ACCDET_INIT": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET init", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_SET_DEBOUNCE": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Set Debounce: state: %d debounce = %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_SET_PWM": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Set PWM: pwmSet = %d, width = %d,thresh = %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_SET_NOT_PLUGGED": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Set Not Plugged", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_SET_PLUGGED": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Set Plugged", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_SET_MIC_BIAS": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Set MIC bias", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_SET_SWITCHED": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Set Switched", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_SET_CHECK_TV": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Set Check TV", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_SET_TVOUT": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Set TV Out", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_NOT_PLUGGED_HANDLER": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Not Plugged Handler: iA = %d, iB = %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_NOT_PLUGGED_STATE_NOT_CHANGE": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Not Plugged state not change", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_NOT_PLUGGED_HANDLER_FAIL": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Not Plugged Handler fail", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_PLUGGED_HANDLER": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Plugged Handler: iA = %d, iB = %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_PLUGGED_HANDLER_FAIL": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Plugged Handler Fail", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_MIC_HANDLER": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Mic Handler: iA = %d, iB = %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_MIC_STATE_NOT_CHANGE": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET mic state not change", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_MIC_HANDLER_FAIL": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Mic Handler Fail", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_SWITCHED_HANDLER": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Switched Handler: iA = %d, iB = %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_HOOK_STATE_NOT_CHANGE": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET hook state not change", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_SWITCHED_HANDLER_FAIL": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Switched Handler Fail", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_CHECK_TV_HANDLER": {
+        "_comment": "Trace reference not found", 
+        "format": "Check TV Handler: iA = %d, iB = %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_CHECK_TV_HANDLER_FAIL": {
+        "_comment": "Trace reference not found", 
+        "format": "Check TV Handler: CheckTvFail", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_TVOUT_HANDLER": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET TvOut Handler: iA = %d, iB = %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_TVOUT_HANDLER_FAIL": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET TvOut Handler Fail", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_NOT_PLUG_DEBOUNCE_CHANGED": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET not plug debounce changed: 0x%x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_HOOK_DEBOUNCE_CHANGED": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET hook debounce changed: 0x%x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_MIC_DEBOUNCE_CHANGED": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET mic debounce changed: 0x%x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_HANDLER": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET Handler", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_HISR_TRC": {
+        "_comment": "Trace reference not found", 
+        "format": "ACCDET HISR", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_STATUS_TRC": {
+        "_comment": "Trace reference not found", 
+        "format": "iA=%d iB=%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_EINT_STATUS_TRC": {
+        "_comment": "Trace reference not found", 
+        "format": "EINT=%d iA=%d iB=%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_HYBRID_ILLEGAL_INTERRUPT1_TRC": {
+        "_comment": "Trace reference not found", 
+        "format": "Audio Buffer Opened: illegal interrupt", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ACCDET_HYBRID_ILLEGAL_INTERRUPT2_TRC": {
+        "_comment": "Trace reference not found", 
+        "format": "Earphone already plugged out: illegal interrupt", 
+        "traceClass": "TRACE_INFO"
+      }
+    }
+  ], 
+  "traceFamily": "PS",
+  "userModule": "",
+  "startGen": "Legacy",
+  "endGen": "Legacy"
+}
\ No newline at end of file
diff --git a/mcu/driver/drv/include/drv_trc_mod_cal_utmd.json b/mcu/driver/drv/include/drv_trc_mod_cal_utmd.json
new file mode 100644
index 0000000..45c1757
--- /dev/null
+++ b/mcu/driver/drv/include/drv_trc_mod_cal_utmd.json
@@ -0,0 +1,545 @@
+{
+  "endGen": "Legacy",
+  "legacyParameters": {}, 
+  "module": "MOD_CAL", 
+  "startGen": "Legacy",
+  "traceClassDefs": [
+    {
+      "TRACE_INFO": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_WARNING": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_ERROR": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_FUNC": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_STATE": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_1": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_2": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_3": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_4": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_5": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_6": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_7": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_8": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_9": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_10": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }
+  ], 
+  "traceDefs": [
+    {
+      "CAL_ERROR": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Error]: %MMM_ERROR_CODE_ENUM", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_INIT": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][%MCAL_TRACE_FLOW_ENUM]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_OPEN": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][%MCAL_TRACE_FLOW_ENUM]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_CTRL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][%MCAL_TRACE_FLOW_ENUM]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_SCENARIO_CTRL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Flow][%MCAL_CTRL_ENUM]:ScenarioID= %MCAL_SCENARIO_ENUM;CtrlCode=%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_CAMERA_FEATURE_CTRL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Flow][%MCAL_CTRL_ENUM]:FeatureID= %MCAL_CAMERA_FEATURE_ENUM;CtrlCode=%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_CCT_FEATURE_CTRL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Flow][%MCAL_CTRL_ENUM]:FeatureID= %d;CtrlCode=%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_PROFILING_FEATURE_CTRL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Flow][%MCAL_CTRL_ENUM]:FeatureID= %MCAL_CAMERA_PROFILING_FEATURE_ENUM;CtrlCode=%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_WEBCAM_FEATURE_CTRL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Flow][%MCAL_CTRL_ENUM]:FeatureID= %MCAL_WEBCAM_FEATURE_ENUM;CtrlCode=%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_ISP_FEATURE_CTRL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Flow][%MCAL_CTRL_ENUM]:FeatureID= %d;CtrlCode=%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_CAMERA_ENGINEER_FEATURE_CTRL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][%d CAL_CTRL][%MCAL_CTRL_ENUM]:FeatureID= %d;CtrlCode=%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_SENSOR_FEATURE_CTRL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Flow][%MCAL_CTRL_ENUM]:FeatureID= %d;CtrlCode=%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_LENS_FEATURE_CTRL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Flow][%MCAL_CTRL_ENUM]:FeatureID= %d;CtrlCode=%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_MATV_FEATURE_CTRL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Flow][%MCAL_CTRL_ENUM]:FeatureID= %MCAL_MATV_FEATURE_ENUM;CtrlCode=%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_VT_FEATURE_CTRL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Flow][%MCAL_CTRL_ENUM]:FeatureID= %MCAL_VT_FEATURE_ENUM;CtrlCode=%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_JPEG_FEATURE_CTRL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Flow][%MCAL_CTRL_ENUM]:FeatureID= %d;CtrlCode=%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_MDP_FEATURE_CTRL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Flow][%MCAL_CTRL_ENUM]:FeatureID= %d;CtrlCode=%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_VIDEO_FEATURE_CTRL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Flow][%MCAL_CTRL_ENUM]:FeatureID= %d;CtrlCode=%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_CLOSE": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][%MCAL_TRACE_FLOW_ENUM]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_FLOW_DEINIT": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][%MCAL_TRACE_FLOW_ENUM]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_CBF_ISP": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Callback Function][ISP][CallBackID:%MCAL_CALLBACK_ID_ENUM][Time:%d]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_CBF_JPEG": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Callback Function][JPEG][CallBackID:%MCAL_CALLBACK_ID_ENUM][Time:%d]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_CBF_PP": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Callback Function][PostProcess][CallBackID:%MCAL_CALLBACK_ID_ENUM][Time:%d]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_CBF_MDP": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Callback Function][MDP][CallBackID:%MCAL_CALLBACK_ID_ENUM][Time:%d]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_CBF_JAIA": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Callback Function][JAIA][CallBackID:%MCAL_CALLBACK_ID_ENUM][Time:%d]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_CBF_IMAGEROT": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Callback Function][ImageRot][CallBackID:%MCAL_CALLBACK_ID_ENUM][Time:%d]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_CBF_TIMEOUT": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Callback Function][StackTimeOut][CallBackID:%MCAL_CALLBACK_ID_ENUM][Time:%d]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_DEMAND_DUMP": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Request][Memory Dump]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_DEMAND_DUMP_SCOPE": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Request][Memory Dump][0x%08X ~ 0x%08X]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_DEMAND_STATE": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Request][CAL State][%MCAL_STATE_ENUM] ", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_DEMAND_ENABLE": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Request][CAL Trace Enable] ", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_DEMAND_DIABLE": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][CAL Request][CAL Trace Disable] ", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_WEBCAM_INIT": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][WEBCAM][Webcam Init] ", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_WEBCAM_CBF_BUF": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][WEBCAM][Webcam ForDoubleBuffer: %d] ", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_WEBCAM_CBF": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][WEBCAM][Webcam CallBack: %d] ", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_WEBCAM_NEEDENCODE": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][WEBCAM][Webcam If NeedEncode-ScenarioId = %d]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_WEBCAM_CAPTURENEXT": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][WEBCAM][Webcam Capture Next Frame-ScenarioId = %d]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_WEBCAM_DROPFRAME": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][WEBCAM][Webcam Drop Encode Req : %d]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_WEBCAM_ENCODEREQ": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][WEBCAM][Webcam Send Encode Request: %d] ", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_WEBCAM_FEATURE_CTL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][WEBCAM][Webcam FeatureCtrl-FeatureId = %MCAL_WEBCAM_FEATURE_ENUM] ", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_WEBCAM_CTL": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][WEBCAM][Webcam Ctrl-ScenarioId = %MCAL_SCENARIO_ENUM CtrlCode = %d] ", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_WEBCAM_ERROR": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][WEBCAM][Webcam Error: %MMM_ERROR_CODE_ENUM] ", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_PROFILING_ZOOM_FACTOR": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL Profiling]ZoomFactor:         %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_PROFILING_NIGHT_MODE": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL Profiling]NightMode:          %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_PROFILING_CAPTURE_COUNT": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL Profiling]CaptureCount:       %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_PROFILING_PREVIEW_FPS": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL Profiling]PreviewFramerate:   %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_PROFILING_CAPTURE_FPS": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL Profiling]CaptureFramerate:   %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_PROFILING_LOG": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL Profiling]Duration:%dms,      %MCAL_CAMERA_PROFILING_LOG_ENUM", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_VIDEO_INFO": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL][Video]CalVideoCtrl: sensor input(%dx%d), record target(%dx%d) , target frame rate : %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "CAL_LOG_OTF": {
+        "_comment": "Trace reference not found", 
+        "format": "[CAL] Force on-the-fly capture", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ISP_RFDESENSE_FH_ENABLE": {
+        "_comment": "Trace reference not found", 
+        "format": "[RF Desense][Camera FH Enabled][RAW]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ISP_RFDESENSE_MCLK_PLK_BG_ON_RAW": {
+        "_comment": "Trace reference not found", 
+        "format": "[RF Desense][Camera MCLK/PCLK background ON][RAW]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ISP_RFDESENSE_MCLK_PLK_BG_ON_YUV": {
+        "_comment": "Trace reference not found", 
+        "format": "[RF Desense][Camera MCLK/PCLK background ON][YUV]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ISP_RFDESENSE_CAM_REG0018_READ": {
+        "_comment": "Trace reference not found", 
+        "format": "[RF Desense][CAM+0018h=0x40, read value %x][YUV]", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ISP_ASD_FACE_LUM": {
+        "_comment": "Trace reference not found", 
+        "format": "[ASD] Face Lum-Capture: %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ISP_ASD_FACE_COMPENSATION_EV": {
+        "_comment": "Trace reference not found", 
+        "format": "[ASD] Face Compensation-Capture EV: %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "ISP_ASD_FACE_COMPENSATION_EV_REAL": {
+        "apiType": "index", 
+        "format": "[ASD] Face Compensation-Capture EV:(real): %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }
+  ], 
+  "traceFamily": "PS"
+}
\ No newline at end of file
diff --git a/mcu/driver/drv/include/drv_trc_mod_msdc_hisr_utmd.json b/mcu/driver/drv/include/drv_trc_mod_msdc_hisr_utmd.json
new file mode 100644
index 0000000..2146403
--- /dev/null
+++ b/mcu/driver/drv/include/drv_trc_mod_msdc_hisr_utmd.json
@@ -0,0 +1,406 @@
+{
+  "legacyParameters": {}, 
+  "module": "MOD_MSDC_HISR", 
+  "traceClassDefs": [
+    {
+      "TRACE_INFO": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_WARNING": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_ERROR": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_FUNC": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_STATE": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_1": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_2": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_3": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_4": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_5": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_6": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_7": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_8": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_9": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_10": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }
+  ], 
+  "traceDefs": [
+    {
+      "MSDC_ERROR_CMDTIMEOUT": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC error: cmd timeout with %x at %x, regs: %x, %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_ERROR_RSPCRC": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC error: cmd resp crcerror with %x at %x, regs: %x, %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_ERROR_DATTIMEOUT": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC error: dat timeout with %x at %x, regs: %x, %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_ERROR_DATCRC": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC error: dat crcerror with %x at %x, regs: %x, %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_ERROR_TUNECLKFAIL": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC error: failed to tune a suitable clk, using MSDC_CFG: %x , MSDC_IOCON:%x currently", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_ERROR_CARDINTERNALECCFAIL": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC error: card has internal ECC fail on sectors, %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_GENERAL_FAIL": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC fail: fail in file %d, line %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_FAIL_WAITNOTBUSY_TIMEOUT": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC fail: polling r1b timeout %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_FAIL_CMD18_DMA_TRANSFER": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC CMD18 DMA transfer fail :%x ", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_READSECTOR_START": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: readSectors start at %x , %d tril with %d RD error before, IOCON: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_READSECTOR_END": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: readSectors end with %x at %x by %x, with throughput %d KB/s", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_READSECTOR_ENTRY": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: readSectors(%x,%x,%x,%x), by %x, pdn: %x, present: %x, init: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_WRITESECTOR_START": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: writeSectors start at %x, %d tril with %d WR error before", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_WRITESECTOR_END": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: writeSectors end with %x at %x by %x, with throughput %d KB/s", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_WRITESECTOR_ENTRY": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: writeSectors(%x,%x,%x,%x), by %x, pdn: %x, present: %x, init: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_R0": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: response0 :%x at %d line", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_CID": {
+        "_comment": "Trace reference not found", 
+        "format": "card's MID : %x,  OIDD : %x ", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_ACMD41OCR": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: ACMD41 OCR :%x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_CMD1OCR": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: MMC CMD1 OCR :%x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_HOTPLUG": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: memory card hot plug, (%x, %x) with card's present:%x at time %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_HOTPLUGILM": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: send ilm for %x card, send_ilm: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_BEFORE_SEND_CMD": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: SDC_CMDSTA %x, SDC_DATASTA %x, SDC_CMD %x, at line %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_CARD_PROGRAMMING": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: period time (including programming): %d ms, %d polling/T", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_R1B_DEBUG": {
+        "_comment": "Trace reference not found", 
+        "format": "r1b status direct entry :%d, LISR %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_R1B_DEBUG_2": {
+        "_comment": "Trace reference not found", 
+        "format": "SDCMDIRQ_Entry_Count %d,SDMCIRQ_Entry_Count %d,SDDATIRQ_Entry_Count %d,SDR1bIRQ_Entry_count %d,SDIOIRQ_Entry_Count %d, SDPINIRQ_Entry_Count %d,%d,%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_EVENTGP_MONITOR": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: event group status %x at line %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_DCL_SD_OPEN": {
+        "_comment": "Trace reference not found", 
+        "format": "SD DCL open: flag : 0x%x, retAddr 0x%x from task 0x%x at time %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_DCL_SDIO_OPEN": {
+        "_comment": "Trace reference not found", 
+        "format": "SDIO DCL open: flag : 0x%x, retAddr 0x%x from task 0x%x at time %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_SDIO_API_DREAD": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: SDIO data read begin(%x,%x,%x,%x,%x,%x), pdn:%x, MSDC_CFG:%x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_SDIO_API_DREAD_END": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: SDIO data read end with status %d, %d blocks(bytes)/s, MSDC_IOCON:%x, SDC_CFG:%x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_SDIO_API_CMD52": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: SDIO CMD52 begin(%x,%x,%x,%x,%x,%x), pdn:%x, MSDC_CFG:%x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_SDIO_API_CMD52_END": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: SDIO CMD52 end with %d, rsp0:%x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_SDIO_API_SET_BLK_SIZE": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: SDIO set function %d block size to %d, status %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_SDIO_API_INIT": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: SDIO init begin", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_SDIO_API_INIT_END": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: SDIO init end with %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_DMA_TRANSFER_CACHED_WRITE": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: count>MSDC_WRITE_THD_POLL,count=%d,threadID=%x ", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "MSDC_INFORM_DMA_TRANSFER_CACHED_READ": {
+        "_comment": "Trace reference not found", 
+        "format": "MSDC info: count>MSDC_READ_THD_POLL,count=%d,threadID=%x ", 
+        "traceClass": "TRACE_INFO"
+      }
+    }
+  ], 
+  "traceFamily": "PS",
+  "userModule": "MSDC",
+  "startGen": "Legacy",
+  "endGen": "Legacy"
+}
\ No newline at end of file
diff --git a/mcu/driver/drv/include/drv_trc_mod_ppp_hw_utmd.json b/mcu/driver/drv/include/drv_trc_mod_ppp_hw_utmd.json
new file mode 100644
index 0000000..c3314aa
--- /dev/null
+++ b/mcu/driver/drv/include/drv_trc_mod_ppp_hw_utmd.json
@@ -0,0 +1,530 @@
+{
+  "endGen": "Legacy",
+  "legacyParameters": {}, 
+  "module": "MOD_PPP_HW", 
+  "startGen": "Legacy",
+  "traceClassDefs": [
+    {
+      "TRACE_INFO": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline", 
+          "TRACE_INFO"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_WARNING": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline", 
+          "TRACE_WARNING"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_ERROR": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline", 
+          "TRACE_ERROR"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_FUNC": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline", 
+          "TRACE_FUNC"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_STATE": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline", 
+          "TRACE_STATE"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_1": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_2": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_3": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_4": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_5": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_6": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_7": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_8": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_9": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_10": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }
+  ], 
+  "traceDefs": [
+    {
+      "PPP_ENCODE_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC Encode", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ENCODE_HISR_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC Encode HISR", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ENCODE_PARA_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC Encode parameters: scp:%d, ecp:%d, op:%d, dest->size:%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ENCODE_PARA_ERROR_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC Encode parameters error: scp:%d, ecp:%d, op:%d, dest->size:%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ENCODE_STATE_ERROR_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC Encode Error PFC not under OK status! stat:%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ENCODE_STATE_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC Encode PFC stat:%d   HW encode src comsume:%d  dst output:%d  duration(tick):%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ENCODE_FINISH_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC Encode API duration(tick):%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_DECODE_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC Decode", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_DECODE_HISR_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC Decode HISR", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_DECODE_PARA_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC Decode parameters: scp:%d, ecp:%d, op:%d, dest->used:%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_DECODE_PARA_ERROR_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC Decode parameters error: scp:%d, ecp:%d, op:%d, dest->used:%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_DECODE_STATE_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC Decode PFC stat:%d   HW decode src comsume:%d  dst output:%d  duration(tick):%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_DECODE_STATE_ERROR_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC Decode Error PFC not under OK status! stat:%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_DECODE_AT_ERROR_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC WARNING_PPP_ESC_ATO_SEEMS_DETECT_AT_IN_PPP_FRAME_DECODE", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_DECODE_ESC_ERROR_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC WARNING_PPP_ESC_ATO_SEEMS_DETECT_ESC_IN_PPP_FRAME_DECODE", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_DECODE_FINISH_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC Decode API duration(tick):%d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_WEITE_BUFFER_FULL_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC write buffer full error", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_OK_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC OK", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ZERO_LENGTH_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC Zero length", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_BUSY_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC BUSY", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_FCS_ERROR_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC FCS_ERROR", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_NOT_0X7E_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC NOT_0X7E", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ADR_CON_ERROR_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC ADR_CON_ERROR", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_INVALID_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC INVALID 0x7d 0x7e", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_RESUME_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC RESUME", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_PROTOCOL_ERROR_DECODING_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC PROTOCOL error in decoding", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_UNKNOWN_ERROR_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC unknown error", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_START_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_START:   addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_CON_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_CON:     addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_PTC_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_PTC:     addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_DSCR_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_DSCR:    addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_SADDR_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_SADDR:   addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_SRC_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_SRC:     addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_USLEN_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_USLEN:   addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_DES_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_DES:     addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_UDLEN_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_UDLEN:   addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_INTEN_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_INTEN:   addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_STAT_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_STAT:    addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_SDRAT_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_SDRAT:   addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ACCM0_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_ACCM0:   addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ACCM1_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_ACCM1:   addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ACCM2_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_ACCM2:   addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ACCM3_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_ACCM3:   addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ACCM4_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_ACCM4:   addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ACCM5_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_ACCM5:   addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ACCM6_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_ACCM6:   addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_DSCR2_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_DSCR2:   addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_DES2_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_DES2:    addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_UDLEN2_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_UDLEN2:  addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_USB1_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_USB1:    addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_USB2_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_USB2:    addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ACCM_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "PFC_ACCM:    addr:%x, value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_ACFC_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "Set PFC_CON = PFC_CON | PFC_ACFC", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "PPP_PFC_MSG": {
+        "_comment": "Trace reference not found", 
+        "format": "Set PFC_CON = PFC_CON | PFC_PFC", 
+        "traceClass": "TRACE_INFO"
+      }
+    }
+  ], 
+  "traceFamily": "PS",
+  "userModule": ""
+}
diff --git a/mcu/driver/drv/include/drv_trc_mod_rtc_hisr_utmd.json b/mcu/driver/drv/include/drv_trc_mod_rtc_hisr_utmd.json
new file mode 100644
index 0000000..bf88ebe
--- /dev/null
+++ b/mcu/driver/drv/include/drv_trc_mod_rtc_hisr_utmd.json
@@ -0,0 +1,560 @@
+{
+  "endGen": "Legacy", 
+  "legacyParameters": {}, 
+  "module": "MOD_RTC_HISR", 
+  "startGen": "Legacy", 
+  "traceClassDefs": [
+    {
+      "TRACE_INFO": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_WARNING": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_ERROR": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_FUNC": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_STATE": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_1": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_2": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_3": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_4": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_5": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_6": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_7": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_8": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_9": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_10": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }
+  ], 
+  "traceDefs": [
+    {
+      "RTC_REPEAT_CALI_ADJUST_COUNT": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC adjust %d count for repeat calibration register", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_REPEAT_CALI_VALUE": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC repeat calibration register value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_REPEAT_CALI_VALUE_EXCEED_MAX": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC repeat calibration value %d exceed max", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_REPEAT_CALI_VALUE_EXCEED_MIN": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC repeat calibration value %d exceed min", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_REPEAT_CALI_PERFORM_CALI": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC repeat calibration perform for %d counts", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_ONESHOT_CALI_PERFORM_COUNT": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC one shot calibration for %d counts, remains %d counts", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_ONESHOT_CALI_VALUE": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC oneshot calibration register value: %x", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_ONESHOT_CALI_FINISH": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC oneshot calibration finish", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_HW_CALI_START_MEASURE_INACCURATE": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC HW cali, start to measure rtc inaccurate: (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_HW_CALI_INIT_MEASURE_ACCURATE_L1_TICK": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC HW cali, init L1 tick: %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_HW_CALI_FINISH_MEASURE_INACCURATE": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC HW cali, finish measuring rtc inaccurate: (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_HW_CALI_FINISH_MEASURE_ACCURATE_L1_TICK": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC HW cali, finish L1 tick: %d, inaccurate ticks: %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_HW_CALI_NO_NEED_TO_CALI": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC HW cali, no need to perform calibration, no diff count: %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_HW_CALI_IN_PROGRESS": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC HW cali, in progress: (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_HW_CALI_INIT_REPEAT_CALI_COUNT": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC HW cali, init repeat cali count: %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_START_POWEROFF_CALI": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, start to do power off cali", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_START_POWEROFF_CALI_TIME": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, current time before power off cali: (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_FINISH_POWEROFF_CALI_TIME": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, current time after power off cali: (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_FINISH_2ND_POWEROFF_CALI": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, wait %d ticks to perform 2nd power off cali", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_AFTER_2ND_POWEROFF_CALI": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, current time after 2nd power off cali: (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_START_POWERON_CALI_TIME": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, start power on cali: (%d:%d:%d), init tick: %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_POWERON_CALI_START_INACCURACY_MEASURE": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, start accuracy measure", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_POWERON_CALI_FINISH_INACCURACY_MEASURE": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, accuracy for one hour: %d ticks", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_POWERON_CALI_START": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, start power on cali: (%d:%d:%d), init tick: %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_WRITE_NVRAM": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, write to NVRAM", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_KAL_EXPIRE_EARLY": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, KAL_timer expired early, expected: %d (tick), now: %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_TIMOUE_NOT_IN_SEC_BOUNDARY": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, timeout not in second boundary: %d (tick)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_TIMOUE_OUT": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali timeout (%d:%d:%d), current frame tick: %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_UPDATE_TIME": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, update time (%d:%d:%d), current frame tick: %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_POWEROFF_CALI_INIT1": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, NVRAM time valid: %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_POWEROFF_CALI_INIT2": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, NVRAM time: %d-%d-%d (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_POWEROFF_CALI_INIT3": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, NVRAM tick diff valud: %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_POWEROFF_CALI_INIT4": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, NVRAM ticks_diff_per_hour: %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_POWEROFF_PERIOD_VALID": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, poweroff period - valid: %d, hours: %d, minutes: %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_CURR_POWER_TIME": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, curr power on time: %d-%d-%d (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_RTC_TIME_IN_MINUTE_BOUNDARY": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, rtc time in minute boundary: %d, delay 6 sec", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_RTC_TIME_IN_ALARM_BOUNDARY": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC SW cali, rtc time in alarm boundary: %d, delay 6 sec", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_INACCURATE_TICK_DURING_POWEROFF": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC cali, inaccurate ticks during power off: %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_ALARM_POWERON_AND_NEED_BACKWARD_TIME": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC cali, alarm power on, but we need to backward time", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SW_CALI_ALARM_POWERON_AND_POWEROFF": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC cali, alarm power on but we backward time so power off", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_TC_INTR_FOR_USER": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC TC intr for user", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_AL_INTR": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC AL intr", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_FORWARD_TIME_1": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC forward time: (%d:%d:%d) forward %d hour, %d min, %d sec", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_FORWARD_TIME_2": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC forward time done: (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_BACKWARD_TIME_1": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC backward time: (%d:%d:%d) backward %d hour, %d min, %d sec", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_BACKWARD_TIME_2": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC backward time done: (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_INIT_TC_TIME": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC initTC time, curr time: %d-%d-%d (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_WRITE_TO_NVRAM": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC write to nvram, nvram time: %d-%d-%d (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_CALI_TIME": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC cali time: %d-%d-%d (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_GET_TIME": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC get time: %d-%d-%d (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_SET_ALARM": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC set alarm: %d-%d-%d (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_GET_AL_TIME": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC get alarm time: %d-%d-%d (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_IS_CONFIG_VALID_ALARM": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC is config valid alarm: %d-%d-%d (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_IS_CONFIG_VALID_TIME": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC is config valid time: %d-%d-%d (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_NOT_CONFIG_VALID_ALARM": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC not config valid alarm: %d-%d-%d (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_NOT_CONFIG_VALID_TIME": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC not config valid time: %d-%d-%d (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_IS_NOT_CONFIG_INVALID_TIME": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC is not config invalid time: %d-%d-%d (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_TIME_VALID": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC time valid: %d-%d-%d (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "RTC_TIME_NOT_VALID": {
+        "_comment": "Trace reference not found", 
+        "format": "RTC time not valid: %d-%d-%d (%d:%d:%d)", 
+        "traceClass": "TRACE_INFO"
+      }
+    }
+  ], 
+  "traceFamily": "PS", 
+  "userModule": ""
+}
\ No newline at end of file
diff --git a/mcu/driver/drv/include/drv_trc_mod_uart_1_hisr_utmd.json b/mcu/driver/drv/include/drv_trc_mod_uart_1_hisr_utmd.json
new file mode 100644
index 0000000..649232a
--- /dev/null
+++ b/mcu/driver/drv/include/drv_trc_mod_uart_1_hisr_utmd.json
@@ -0,0 +1,196 @@
+{
+  "endGen": "Legacy",
+  "legacyParameters": {}, 
+  "module": "MOD_UART_1_HISR", 
+  "startGen": "Legacy",
+  "traceClassDefs": [
+    {
+      "TRACE_INFO": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_WARNING": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_ERROR": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_FUNC": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_STATE": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_1": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_2": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_3": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_4": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_5": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_6": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_7": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_8": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_9": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }, 
+    {
+      "TRACE_GROUP_10": {
+        "debugLevel": "Ultra-Low", 
+        "tag": [
+          "Baseline"
+        ], 
+        "traceType": "Public"
+      }
+    }
+  ], 
+  "traceDefs": [
+    {
+      "UART_RX_VFIFO_TIMEOUT_INT": {
+        "_comment": "Trace reference not found", 
+        "format": "UART port:%d  recive %d data---VFIFO Rx timeOut interrupt", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "UART_RX_VFIFO_INT": {
+        "_comment": "Trace reference not found", 
+        "format": "UART port:%d  recive %d data---VFIFO Rx interrupt", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "UART_RX_MCU_MODE_INT": {
+        "_comment": "Trace reference not found", 
+        "format": "UART port:%d  recive %d data---MCU mode Rx MCU mode interrupt", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "UART_TX_VFIFO_U_SendISRData_VFIFO": {
+        "_comment": "Trace reference not found", 
+        "format": "UART VFIFO Tx  U_SendISRData_VFIFO()---len %d,left %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "UART_TX_VFIFO_U_SendData_VFIFO": {
+        "_comment": "Trace reference not found", 
+        "format": "UART VFIFO Tx  U_SendData_VFIFO()---len %d,left %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "UART_TX_VFIFO_U_PutBytes_VFIFO": {
+        "_comment": "Trace reference not found", 
+        "format": "UART VFIFO Tx  U_PutBytes_VFIFO()---len %d,left %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }, 
+    {
+      "UART_TX_VFIFO_U_PutISRBytes_VFIFO": {
+        "_comment": "Trace reference not found", 
+        "format": "UART VFIFO Tx  U_PutISRBytes_VFIFO()---len %d,left %d", 
+        "traceClass": "TRACE_INFO"
+      }
+    }
+  ], 
+  "traceFamily": "PS", 
+  "userModule": ""
+}
\ No newline at end of file
diff --git a/mcu/driver/drv/include/drvtest_no_use.h b/mcu/driver/drv/include/drvtest_no_use.h
new file mode 100644
index 0000000..3734ffe
--- /dev/null
+++ b/mcu/driver/drv/include/drvtest_no_use.h
@@ -0,0 +1,77 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    drvtest.h
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   This Module defines for driver test task
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+typedef struct {
+	LOCAL_PARA_HDR
+	kal_kal_uint32 id;
+} drvtest_localpara_struct;
+
+
diff --git a/mcu/driver/drv/include/fota.h b/mcu/driver/drv/include/fota.h
new file mode 100644
index 0000000..564b4a1
--- /dev/null
+++ b/mcu/driver/drv/include/fota.h
@@ -0,0 +1,432 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2006
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   fota.h
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   This is the header of FOTA firmware update download module
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+#ifndef __FOTA_H__
+#define __FOTA_H__
+
+/*******************************************
+*   Include File      
+********************************************/
+
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+#include "fat_fs.h"
+#include "DrvFlash.h"
+#include "fota_error.h"
+#include "custom_img_config.h"
+
+/*******************************************
+*   Structure and Macro Definition      
+********************************************/
+#define FOTA_BUFFER_SIZE FOTA_FLASH_MAX_PAGE_SIZE
+#define FOTA_FRAME_TICK 70
+
+typedef kal_int32 (*CALLBACK_Auth_FUNC)(void* Header);
+typedef kal_int32 (*CALLBACK_Decrypt_FUNC)(void* EncryptBuffer);
+
+//#if !defined(_NAND_FLASH_BOOTING_)
+#if !defined(__FOTA_DM__)
+
+typedef struct {
+   kal_int32 Status;
+   kal_uint32 FlashBaseAddr; 
+   kal_uint32 OriginalBaseAddr;
+   kal_uint32 SpareBaseAddr;
+   kal_uint32 SpareStartBlkIndex;
+   kal_uint32 TotalFOTALength;
+   kal_uint32 SpareCurrAddr; 
+   kal_uint32 NextBlockAddr;
+   kal_uint32 NextBlkOffset;
+   FlashRegionInfo* NORRegionInfo;
+   kal_uint32 ImageChecksum;
+   kal_uint32 ImageStartAddr;
+   kal_uint32 ImageLength;
+   kal_uint32 BufferIndex;
+   CALLBACK_Auth_FUNC Auth;
+   CALLBACK_Decrypt_FUNC Decrypt;
+   kal_uint32  FOTABuffer[FOTA_BUFFER_SIZE>>2];
+} FOTA_DATA;
+
+#else /* defined(_NAND_FLASH_BOOTING_) */
+
+typedef struct {
+   kal_int32                 Status;
+   kal_uint32                SpareCurrWriteAddr; 
+   kal_uint32                SpareNextWriteBlockAddr;
+   kal_uint32                SpareCurrReadAddr; 
+   kal_uint32                SpareNextReadBlockAddr;
+   kal_uint32                BufferIndex;
+   kal_uint32                FOTAWriteBuffer[FOTA_BUFFER_SIZE>>2];
+   kal_uint32                FOTAReadBuffer[FOTA_BUFFER_SIZE>>2];
+} FOTA_DATA;
+
+#endif /* !defined(_NAND_FLASH_BOOTING_) */
+
+typedef struct {
+   kal_uint32 UpdateFlag;
+   kal_uint32 StartAddr;
+   kal_uint32 ImageLen;
+} FUE_FLAG;
+
+typedef struct {
+   kal_char	 PlatformID[128]; 
+   kal_uint32 FATBeginAddr;
+   kal_uint32 FATLength;
+   kal_uint32 ImageLength;
+   kal_uint32 ImageCheckSum;
+   kal_uint32 StartAddr;
+   kal_uint32 HeaderCheckSum;
+} CompressImageHeader;
+
+
+typedef enum {
+  FOTA_UPDATE_SUCCEEDED,
+  FOTA_UPDATE_FAILED,
+  FOTA_UPDATE_NONE,
+  FOTA_UPDATE_END
+} FOTA_update_result; 
+
+/*******************************************
+*   Function and Variable Definition      
+********************************************/
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Initialize
+DESCRIPTION
+   FOTA Initialization API
+   1. Initialize data structure and progress initial step
+   2. Register customized authentication function or encryption function
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+extern kal_int32 FOTA_Initialize(void);
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_WriteData
+DESCRIPTION
+   FOTA write data API
+   1. This function is used to write data to spare image pool
+   2. This API only allow sequentially writing mechanism
+   3. Authentication mechanism is executed during writing
+PARAMETER
+   Length: the length of writing (Unit: Bytes)
+   Buffer: the start address of buffer
+RETURN
+   0: means pass write success (ERROR_FOTA_SUCCESS)
+   < 0: writing action is fail
+      ERROR_FOTA_AUTH_ROMINFO: authentication fail, can't find rom info
+      ERROR_FOTA_AUTH_FATBEGIN: authentication fail, fat begin address is different
+      ERROR_FOTA_AUTH_FATLEN: authentication fail, fat length is different
+      ERROR_FOTA_AUTH_HCHECKSUM: authentication fail, header checksum fail
+      ERROR_FOTA_AUTH_ID: authentication fail, platform id is different
+      ERROR_FOTA_AUTH_VERSION: authentication fail, downgrade is not allowed
+      ERROR_FOTA_AUTH_IMAGELEN: authentication fail, image length too large
+	 ERROR_FOTA_AUTH_FAIL: authentication fail before
+	 ERROR_FOTA_OVERRANGE: write over the spare image pool range
+	 ERROR_FOTA_NOT_INITIALIZED: not call FOTA_Initialize before
+--------------------------------------------------------------------------------- */
+extern kal_int32 FOTA_WriteData(kal_uint32 Length, void* Buffer);
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_ReadData
+DESCRIPTION
+   FOTA read data API
+   1. This function is used to read data from spare image pool
+   2. This API only support sequentially read operation, i.e. from low address to high address
+PARAMETER
+   Length: the length of writing (Unit: Bytes)
+   Buffer: the start address of buffer
+RETURN
+   0: means pass write success (ERROR_FOTA_SUCCESS)
+   < 0: writing action is fail
+      ERROR_FOTA_AUTH_ROMINFO: authentication fail, can't find rom info
+      ERROR_FOTA_AUTH_FATBEGIN: authentication fail, fat begin address is different
+      ERROR_FOTA_AUTH_FATLEN: authentication fail, fat length is different
+      ERROR_FOTA_AUTH_HCHECKSUM: authentication fail, header checksum fail
+      ERROR_FOTA_AUTH_ID: authentication fail, platform id is different
+      ERROR_FOTA_AUTH_VERSION: authentication fail, downgrade is not allowed
+      ERROR_FOTA_AUTH_IMAGELEN: authentication fail, image length too large
+	 ERROR_FOTA_AUTH_FAIL: authentication fail before
+	 ERROR_FOTA_OVERRANGE: write over the spare image pool range
+	 ERROR_FOTA_NOT_INITIALIZED: not call FOTA_Initialize before
+--------------------------------------------------------------------------------- */
+extern kal_int32 FOTA_ReadData(kal_uint32 Length, void* Buffer);
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Get_DownloadedPackageSize
+DESCRIPTION
+   return currently downloaded package size
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_Get_DownloadedPackageSize(kal_uint32 *curr_size);
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_ClearPackageReservoir
+DESCRIPTION
+   clear downloaded update package
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+        ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_ClearPackageReservoir(void);
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Get_AvailablePackageSpace
+DESCRIPTION
+   return currently downloaded package size
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_Get_AvailablePackageSpace(kal_uint32 *avail_size);
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Get_TotalPackageSpace
+DESCRIPTION
+   return currently downloaded package size
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_Get_TotalPackageSpace(kal_uint32 *avail_size);
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_WriteUpdateRecord
+DESCRIPTION
+   FOTA update state information write API
+   download client and update agent use this information to communicate with each other
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+extern kal_int32 FOTA_WriteUpdateRecord(FOTA_Custom_Update_Info* record);
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_ReadUpdateRecord
+DESCRIPTION
+   FOTA update state information read API
+   download client and update agent use this information to communicate with each other
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+extern kal_int32 FOTA_ReadUpdateRecord(FOTA_Custom_Update_Info* record);
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Finalize
+DESCRIPTION
+   FOTA finalization API
+   1. compare calculated checksum with image checksum in the header after 
+       whole image is written 
+   2. mark the status to UPDATE_NEEDED 
+PARAMETER
+   void
+RETURN
+   0: means pass error check step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_AUTH_FAIL: authentication fail, final step is not allowed
+      ERROR_FOTA_IMAGE_CHECKSUM: image checksum error
+--------------------------------------------------------------------------------- */
+extern kal_int32 FOTA_Finalize(void);
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_FOTA_Reg_Auth
+DESCRIPTION
+   FOTA register function of authentication
+   register the authentication function if needed
+PARAMETER
+   Auth: the call back decrypt function which want to register
+RETURN
+   NULL
+--------------------------------------------------------------------------------- */
+extern void FOTA_Reg_Auth(CALLBACK_Auth_FUNC Auth);
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Reg_Decrypt
+DESCRIPTION
+   FOTA register function of decryption, only allow symmetric encryption algorithm
+   register the decryption function if needed
+PARAMETER
+   Decrypt: the call back decrypt function which want to register
+RETURN
+   NULL
+--------------------------------------------------------------------------------- */
+extern void FOTA_Reg_Decrypt(CALLBACK_Decrypt_FUNC Decrypt);
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_InitializeUpdateRecord
+DESCRIPTION
+   create an update record block or find out the existing update record block 
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_InitializeUpdateRecord(void);
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Inform_Update_State
+DESCRIPTION
+   Query the status of triggered update process
+PARAMETER
+   NONE
+RETURN
+   NULL
+--------------------------------------------------------------------------------- */
+FOTA_update_result FOTA_Inform_Update_State(void);
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Start_Download_State
+DESCRIPTION
+   Download client use this function to query the result of update process
+PARAMETER
+   NULL
+RETURN
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_Start_Download_State(void);
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Start_Update_State
+DESCRIPTION
+   Download client use this function to query the result of update process
+PARAMETER
+   NULL
+RETURN
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_Start_Update_State(void);
+
+extern FOTA_DATA FOTAData;
+
+#endif //__FOTA_H__
diff --git a/mcu/driver/drv/include/msdc_fake_kal.h b/mcu/driver/drv/include/msdc_fake_kal.h
new file mode 100644
index 0000000..c398aaf
--- /dev/null
+++ b/mcu/driver/drv/include/msdc_fake_kal.h
@@ -0,0 +1,115 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2007
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   msdc_fake_kal.h
+ *
+ * Project:
+ * --------
+ *   Maui
+ *
+ * Description:
+ * ------------
+ *   MSDC fake kal header file for bootloader porting
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+ 
+#ifndef _MSDC_FAKE_KAL_H_
+#define _MSDC_FAKE_KAL_H_
+
+#if defined(__UBL__) && defined(__CARD_DOWNLOAD__)
+
+#include "stack_ltlcom.h" //MSBB change #include "app_ltlcom.h"         // for ilm_struct
+
+//typedef void            *kal_taskid;
+typedef char            kal_char;
+
+typedef signed char     kal_int8;
+typedef short           kal_int16;
+typedef int             kal_int32;
+typedef unsigned char   kal_uint8;
+typedef unsigned short  kal_uint16;
+typedef unsigned int    kal_uint32;
+
+typedef unsigned int    rm_kal_wait_mode;
+typedef unsigned int    rm_kal_status;
+
+//function define
+#define kal_mem_set                 memset
+
+//extern kal_taskid kal_get_current_thread_ID(void);
+
+extern ilm_struct *allocate_ilm(module_type module_id);
+extern kal_bool msg_send_ext_queue(ilm_struct *ilm_ptr);
+
+extern void IRQMask(kal_uint8);
+extern void IRQUnmask(kal_uint8);
+
+#endif //defined(__UBL__) && defined(__CARD_DOWNLOAD__)
+
+#endif //_MSDC_FAKE_KAL_H_
+
diff --git a/mcu/driver/drv/include/msdc_lsd.h b/mcu/driver/drv/include/msdc_lsd.h
new file mode 100644
index 0000000..6689a24
--- /dev/null
+++ b/mcu/driver/drv/include/msdc_lsd.h
@@ -0,0 +1,248 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   msdc_lsd.h
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   header file of software SD/MMC controller interface 
+ *   
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================ 
+ ****************************************************************************/
+ #ifndef MSDC_LSD_H
+ #define MSDC_LSD_H
+
+/*RHR*/
+//MSBB remove #include "kal_non_specific_general_types.h"
+#include "drv_features.h"
+/*RHR*/
+
+ /*following 2 definitions should be defined in this file*/
+#define LSD_HPI
+#define LSD_CONTROLLER
+
+
+#define	LSD_LCDARB_FREE	0
+#define	LSD_LCDARB_LCD	1
+#define	LSD_LCDARB_SD		2
+#define	LSD_LCDARB_CAL	3
+
+/*DRV_LSD macro definition*/
+#define	LSD_MSDC_CFG	0
+#define	LSD_MSDC_STA	1
+#define	LSD_MSDC_INT	2
+#define	LSD_MSDC_DAT	3 
+#define	LSD_MSDC_PS		4
+#define	LSD_MSDC_IOCON	5
+#define	LSD_SDC_CFG		6
+#define	LSD_SDC_CMD		7
+#define	LSD_SDC_ARG		8
+#define	LSD_SDC_STA		9
+#define	LSD_SDC_RESP0	10
+#define	LSD_SDC_RESP1	11
+#define	LSD_SDC_RESP2	12
+#define	LSD_SDC_RESP3	13
+#define	LSD_SDC_CMDSTA	14
+#define	LSD_SDC_DATSTA	15
+#define	LSD_SDC_CSTA	16
+#define	LSD_SDC_IRQMASK0	17
+#define	LSD_SDC_IRQMASK1	18
+#define	LSD_CMD47_46	0x40
+#define	LSD_CMD55		0x37
+#define	LSD_CMD41		0x29
+
+typedef enum {
+	LSD_SPEED_INIT = 0,
+	LSD_SPEED_26M = 2,
+	LSD_SPEED_52M = 3
+} T_LSD_SPEED;
+
+typedef enum {
+	LSD_cardInsertion = 0,
+	LSD_cardRemoval = 1
+}T_LSD_CardDetection;
+
+typedef enum {
+	LSD_MSDCCLKBPI2 = 0,
+	LSD_MSDCCLKBPI3 = 1
+}T_LSD_MSDCCLK;
+
+
+
+
+
+extern kal_uint32 LSD_dbgInfo[];
+extern kal_uint32 LSD_dbgInfoIndex;
+#define LSD_DBG_INFO_NUM	128
+
+#define LSD_NOT_SUPPORTED 0x1
+
+void LSD_HISR_Registration(void);
+kal_bool LSD_Support(void);
+void LSD_SetBit32(kal_uint32 address,kal_uint32 maskValue);
+void LSD_ClrBit32(kal_uint32 address,kal_uint32 maskValue);
+void LSD_WriteReg32(kal_uint32 address, kal_uint32 data);
+void LSD_ReadReg16(kal_uint32 adrs, kal_uint16 *pdata);
+void LSD_ReadReg32(kal_uint32 adrs, kal_uint32 *pdata);
+kal_uint32 LSD_Reg32(kal_uint32 adrs);
+void LSD_PDNControl(kal_bool ON);
+void LSD_CLR_FIFO(void);
+void LSD_Reset(void);
+kal_uint32 LSD_IS_BUSY(void);
+void LSD_HostSetClock(int speed);
+void LSD_readFIFO(kal_uint32 *adrs, kal_uint32 count);
+void LSD_HostSetBuffer(kal_uint8 *datPtr);
+T_LSD_CardDetection LSD_cardDetection(void);
+
+/*following APIs is provided to FMT, DMT cant see DRV_LSD, can't use DRV_LSD seperate*/
+#ifdef __MTK_TARGET__
+void MSDC_unsealMountOperation(void);
+void NotifyFMTWhenCardPresent(void);
+void LSD_Slower(kal_uint8 slowFactor);
+#else
+#define MSDC_unsealMountOperation()
+#define NotifyFMTWhenCardPresent()
+#define LSD_Slower(a)
+#endif
+
+#ifdef DRV_LSD
+#define LSD_STOP_IMMEDIATLY //this should only be seen in DRV_LSD scope, can't be seen in other platform
+
+void LSD_TakeControl(kal_uint32 owner);
+void LSD_GiveControl(kal_uint32 owner);
+void LSD_startFastFormat(void);
+void LSD_closeFastFormat(void);
+#else
+#define LSD_startFastFormat
+#define LSD_closeFastFormat
+#define LSD_TakeControl(a)
+#define LSD_GiveControl(a)
+#endif
+
+ #endif
diff --git a/mcu/driver/drv/src/BC_drv.c b/mcu/driver/drv/src/BC_drv.c
new file mode 100644
index 0000000..b687455
--- /dev/null
+++ b/mcu/driver/drv/src/BC_drv.c
@@ -0,0 +1,164 @@
+
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    BC_drv.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   Driver 0f Bit Copy.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+#include "drv_comm.h"
+#include "intrCtrl.h"
+#include "drv_hisr.h"
+#include "BC_drv.h"
+
+#if defined(__3G_F8F9BC_HW_DRV_V1__)
+
+static kal_mutexid          BC_mutex;
+
+
+/*****************************************************************************
+ * FUNCTION
+ *   F8Cipher
+ *
+ * DESCRIPTION
+ *   Do the F8 Cipher funtion.
+ *
+ * PARAMETERS
+ *   src             [IN] : source data pointer
+ *   srcOffset       [IN] : source data bit offset
+ *   dest            [IN] : destination data pointer
+ *   destOffset      [IN] : destination data bit offset
+ *   length          [IN] : total bit length
+ *
+ * RETURNS
+ *   None
+ *****************************************************************************/
+
+
+void BitCopy(const kal_uint8 *src, kal_uint16 srcOffset, kal_uint8 *dest, kal_uint16 *destOffset, kal_uint16 length)
+{
+	
+     kal_uint32	 Input32Temp, BC_it;
+     kal_uint32  srcStartAddr, dstStartAddr;
+     kal_uint16  destOffsetTemp = *destOffset; 
+     
+     srcStartAddr = (kal_uint32) (src + ( srcOffset / 8 ));
+     srcOffset = srcOffset % 8;
+     
+     dstStartAddr = (kal_uint32) (dest + ( (*destOffset) / 8 ));
+     (*destOffset) = (*destOffset) % 8;
+     
+     
+     if (!BC_mutex){
+         BC_mutex = kal_create_mutex("BC_mutex");}
+      
+     
+     kal_take_mutex(BC_mutex);
+        
+     //reset all register   
+	  DRV_WriteReg32(BC_REG_START,0);       
+	   
+	  //input source addr
+	  DRV_WriteReg32(BC_REG_SRC, ((kal_uint32)(srcStartAddr)));    
+	   
+	  //output destination addr   
+	  DRV_WriteReg32(BC_REG_DST, ((kal_uint32)(dstStartAddr)));      
+	   
+	   
+	  //output destination last byte addr 
+	  Input32Temp = ((length - (8 - (*destOffset))) > 0) ? (kal_uint32)(dstStartAddr + ((length - (8 - (*destOffset)) + 7) / 8)) : (kal_uint32)dstStartAddr;
+	  DRV_WriteReg32(BC_REG_LDST, ((kal_uint32)Input32Temp));   
+	   
+	   
+	  //input copy length 
+	  Input32Temp = 0;
+     Input32Temp = length & 0x0000FFFF;
+	   DRV_WriteReg32(BC_REG_SIZE, ((kal_uint32)Input32Temp));                 
+	   
+	   
+	  //set wo and ro(also reset all)
+	  Input32Temp = 0;
+     Input32Temp = (kal_uint32)(( ((kal_uint32)(*destOffset))<<4) | ((kal_uint32)srcOffset) | (0x00030000));
+	  DRV_WriteReg32(BC_REG_CON, (kal_uint32)Input32Temp);               
+	   
+	   
+	  //start the BC engine 
+     DRV_WriteReg32(BC_REG_START, 0x00008000);       
+	   	
+	   	
+	   //polling completed interrupt	
+	   while(1){  
+	     BC_it = DRV_Reg32(BC_REG_STA);
+        if((BC_it&0x00000002)!=0)
+	   		break;
+	   }
+	   
+	   kal_give_mutex(BC_mutex);
+	   
+	   (*destOffset) = destOffsetTemp + length;
+} 
+
+#endif /* __3G_F8F9BC_HW_DRV_V1__ */
diff --git a/mcu/driver/drv/src/CAS_ICC_al_Nagra.c b/mcu/driver/drv/src/CAS_ICC_al_Nagra.c
new file mode 100644
index 0000000..fd2301a
--- /dev/null
+++ b/mcu/driver/drv/src/CAS_ICC_al_Nagra.c
@@ -0,0 +1,442 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    CAS_ICC_al_Nagra.c 
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   This file is to implement API for smart card CA solution of Nagra's SMD card.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+
+/*****************************************************************************/
+/* FICHIERS A INCLURE                                                        */
+/*****************************************************************************/
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+#include  	"drv_comm.h"
+#include 	"reg_base.h"
+#include "dma_sw.h"
+#include 	"intrCtrl.h"
+#include    "sim_hw.h"
+#include "sim_al.h"
+#include "sim_sw_comm.h"
+#include "cache_sw.h"
+#include "init.h"
+
+#include "..\..\vendor\cmmb\nagra\inc\ca_icc.h"
+#include "..\..\media\common\include\med_trc.h"
+
+/*****************************************************************************/
+/* DECLARATION DES CONSTANTES LOCALES                                        */
+/*****************************************************************************/
+
+#define ICC_MAX_READER_NUMBER 2
+
+#define ICC_MAX_SEND_TRY 3 // max number of send try in case of failure
+
+#define MAX_READERNAME 52
+
+#define READER_NAME "TFlash USB GSI (823533310050) 00 00"
+
+/*****************************************************************************/
+/* DECLARATION DES TYPES LOCAUX                                              */
+/*****************************************************************************/
+/*
+typedef struct {
+	char ident[MAX_READERNAME];
+	bool lock;
+	bool exclusivity;
+	e_ReaderProtocol protocol;
+	unsigned int rate;
+} tReaderInfo;
+
+typedef struct {
+	int ReaderId;
+	TIccEventNotification callback;
+} tCardEventCallback;
+
+*/
+
+#define IMPLEMENTING_ASSERT	ASSERT(0)
+
+typedef struct
+{
+	sim_HW_cb	*iccHwCb;
+#if 0	
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+} TIccGlobals;
+
+
+/*****************************************************************************/
+/* DECLARATION DES FONCTIONS STATIQUES                                       */
+/*****************************************************************************/
+/*
+TIccStatus IccSetReaders(int Nb, char* Ident, int Protocol, unsigned int Rate);
+tCardEventCallback *CardEventCallbackCreate(int ReaderId, TIccEventNotification Callback);
+void CardEventCallbackDestroy(tCardEventCallback *CardEventCallback);
+void CardEvent(void *Event, void *Extra);
+static TIccStatus GetReaderFromSessionId(TIccSessionId xSessionId,
+										 TIccGlobals ** pIccReader);
+static void SendNoAvailableSCNotif(void * CB);
+*/
+/*****************************************************************************/
+/* DECLARATION DES VARIABLES STATIQUES                                       */
+/*****************************************************************************/
+//static tReaderInfo readers[ICC_MAX_READER_NUMBER];
+static kal_bool readersInit = KAL_FALSE; //to make record whether DALICCInit is called or not, to make usre it is called onece
+static int gReaderNb=0;
+static TIccGlobals gIcc[ICC_MAX_READER_NUMBER];
+static kal_bool gIccRegistered = KAL_FALSE;
+kal_semid casIccArb;
+
+TIccEventNotification   gIccEventNotificationCB;
+
+extern sim_HW_cb	simHWCbArray[];
+
+/*****************************************************************************/
+/* CORPS DES FONCTIONS                                                       */
+/*****************************************************************************/
+
+
+TIccStatus DalIccInit()
+{
+	if (KAL_TRUE == readersInit){
+		dbg_print("ERROR: already initialized!!");
+		return ICC_ERROR;	
+	}
+
+
+
+	casIccArb = kal_create_sem("cas icc", 1);
+	
+	/*need to get HW information about which card slot is for SMD*/
+	
+	readersInit = KAL_TRUE;
+}
+
+
+// this function is meant to be called only once !!!!!!!
+TIccStatus iccRegister(TIccEventNotification   xIccEventNotification,
+					   TIccRegistrationId*     pxRegistrationId){
+	TIccStatus Status=ICC_ERROR;
+	//linrdStatus LrdStatus ;
+	//tEventListener *Listener = NULL;
+	//int loop;
+	kal_bool IccFound = KAL_FALSE;
+	sim_power_enum resultVoltage;
+	sim_HW_cb	*hw_cb;
+	usim_status_enum resetStatus = USIM_NO_INSERT;
+
+
+	if (pxRegistrationId==NULL || xIccEventNotification==NULL)
+		goto End;
+
+	kal_take_sem(casIccArb, 1);
+	if (KAL_TRUE == gIccRegistered) {
+		dbg_print("ERROR:  an application is already registered");
+		Status=ICC_ERROR;
+		kal_give_sem(casIccArb);
+		goto End;
+	}
+	if (KAL_FALSE == readersInit){
+		dbg_print("ERROR: ICC initialized");
+		Status=ICC_ERROR;
+		kal_give_sem(casIccArb);
+		goto End;
+	}
+
+	// limitation: only one appli registered at once !!!
+	*pxRegistrationId=1;
+	if(NULL != gIccEventNotificationCB)
+		ASSERT(0);
+	gIccEventNotificationCB=xIccEventNotification;
+	gIccRegistered = KAL_TRUE;
+	kal_give_sem(casIccArb);
+	hw_cb = &simHWCbArray[get_CAS_icc_logicalNum()];
+	gIcc[0].iccHwCb = hw_cb;
+	/*get car's existence, if it exists, calls callback*/
+	resetStatus = L1sim_Reset_All(UNKNOWN_POWER_CLASS, &resultVoltage, KAL_FALSE, SIM_ICC_APPLICATION_CMMB_SMD);
+	if(USIM_NO_ERROR == resetStatus)
+		xIccEventNotification(ICC_EVENT_CARD_INSERTED_SINGLE_CLIENT_SUPPORT, (kal_uint32)hw_cb, NULL, 0);
+	else
+		xIccEventNotification(ICC_EVENT_NO_AVAILABLE_CARD, ICC_SESSION_ID_NONE, NULL, 0);
+
+	Status=ICC_NO_ERROR;
+
+
+ End:
+    MD_TRC_CMMB_CA_NAGRA_ICC_REGISTER(Status, *pxRegistrationId, (resetStatus == USIM_NO_ERROR)? ICC_EVENT_CARD_INSERTED_SINGLE_CLIENT_SUPPORT : ICC_EVENT_NO_AVAILABLE_CARD);
+	return Status;
+
+}
+
+
+TIccStatus iccCancelRegistration(TIccRegistrationId    xRegistrationId)
+{
+	
+	TIccStatus Status=ICC_ERROR;
+	int loop;
+	//linrdStatus LrdStatus ;
+
+	if(KAL_TRUE != gIccRegistered)
+		ASSERT(0);
+
+	kal_take_sem(casIccArb, 1);
+	
+	// limitation: only one appli registered at once !!!
+	if (xRegistrationId==1) {
+		gIccRegistered = KAL_FALSE;
+		Status = ICC_NO_ERROR;
+		gIccEventNotificationCB = NULL;
+	}
+	
+	
+	kal_give_sem(casIccArb);
+	
+    MD_TRC_CMMB_CA_NAGRA_ICC_CANCEL_REGISTER(Status, xRegistrationId);
+
+	return Status;
+}
+
+
+TIccStatus iccT0Exchange(
+        TIccSessionId      xSessionId,
+        kal_uint32              xCommandLen,
+  const kal_uint8*    pxCommand,
+        kal_uint32                xReceiveMaxLen,
+        kal_uint32*              pxReceiveLen,
+        kal_uint8*      pxReceiveBytes
+)
+{
+	//linrdStatus LrdStatus;
+	TIccStatus Status=ICC_ERROR;
+	TIccGlobals * pIccReader;
+	sim_HW_cb *hw_cb;
+	sim_status SW;
+	kal_uint8 cmd_case1[5];
+	kal_uint8 *tx;
+
+
+	if((TIccSessionId)gIcc[0].iccHwCb != xSessionId || SIM_HW_CB_HEAD != ((sim_HW_cb *)xSessionId)->head || SIM_HW_CB_TAIL != ((sim_HW_cb *)xSessionId)->tail)
+		return ICC_ERROR_SESSION_ID;
+
+  	hw_cb = (sim_HW_cb *)xSessionId;
+
+	
+
+	if (pxCommand==NULL || pxReceiveBytes==NULL || pxReceiveLen==NULL || 2 > xReceiveMaxLen || 4 > xCommandLen){
+		Status=ICC_ERROR;
+		goto End;
+	}
+
+	tx = (kal_uint8 *)pxCommand;
+
+	*pxReceiveLen = xReceiveMaxLen-2; //thie value includes status word from upper layer, we have to decrease this.
+
+	if(5 != xCommandLen && 0 != *pxReceiveLen)/*usim_case_4*/
+	{
+		/*in our driver, we will ignore tx last byte in usim_case4 processing, so we have to add 1 here*/
+		xCommandLen ++;
+	}
+	else if(5 > xCommandLen && 0 == *pxReceiveLen)/*sim_case_1*/
+	{
+		/*
+			tx length 4 and no rx, this is cmd case 1 in sim spec, but our driver expect the tx length should be 5
+			so we have to workaround this part.
+		*/
+		if(4 != xCommandLen)
+			ASSERT(0);
+
+		kal_mem_cpy(cmd_case1, pxCommand, xCommandLen);
+		cmd_case1[4] = 0;
+		tx = cmd_case1;
+		xCommandLen = 5;
+	}
+	if(0 == *pxReceiveLen){ /*in MTK's driver, we use rxPtr to tell whether it is case 3 or case 4, we should modify this argument*/
+		SW = L1sim_Cmd_All(tx, &xCommandLen, NULL, pxReceiveLen, SIM_ICC_APPLICATION_CMMB_SMD);
+	}
+	else{
+		SW = L1sim_Cmd_All(tx, &xCommandLen, pxReceiveBytes, pxReceiveLen, SIM_ICC_APPLICATION_CMMB_SMD);
+	}
+
+	*pxReceiveLen = (*pxReceiveLen) +2;
+	if(0x0000 == SW)
+		Status=ICC_ERROR_TIMEOUT;
+	else{
+		Status=ICC_NO_ERROR;
+		pxReceiveBytes[(*pxReceiveLen)-2] = (SW >>8);
+		pxReceiveBytes[(*pxReceiveLen)-1] = (SW & 0xff);
+	}
+
+ End:
+    MD_TRC_CMMB_CA_NAGRA_ICC_T0_EXCHANGE(Status, xSessionId, xCommandLen, tx, *pxReceiveLen);
+	return Status;	
+}
+
+
+
+
+TIccStatus iccSmartcardReset( TIccSessionId xSessionId, TBoolean xColdReset)
+{
+
+	kal_bool coldReset;
+	TIccStatus Status=ICC_ERROR;
+	//linrdStatus LrdStatus ;
+	TIccGlobals * pIccReader;
+	sim_power_enum resultVoltage;
+	sim_HW_cb *hw_cb;
+
+	if((TIccSessionId)gIcc[0].iccHwCb != xSessionId)
+		ASSERT(0);
+
+  	hw_cb = (sim_HW_cb *)xSessionId;
+	
+
+	if(TRUE == xColdReset)
+		coldReset = KAL_TRUE;
+	else if(FALSE == xColdReset)
+		coldReset = KAL_FALSE;
+	else
+		ASSERT(0);
+	
+	L1sim_Reset_All(UNKNOWN_POWER_CLASS, &resultVoltage, coldReset, SIM_ICC_APPLICATION_CMMB_SMD);
+
+		Status=ICC_NO_ERROR;
+
+ End:
+    MD_TRC_CMMB_CA_NAGRA_ICC_SMARTCARD_RESET(Status, xColdReset);
+	return Status;
+}
+
+
+TIccStatus iccModeChange( TIccSessionId       xSessionId,
+						  TIccAccessMode      xMode)
+{
+    MD_TRC_CMMB_CA_NAGRA_ICC_MODE_CHANGE(xSessionId, xMode);
+	if((TIccSessionId)gIcc[0].iccHwCb != xSessionId)
+		return ICC_ERROR_SESSION_ID;
+	IMPLEMENTING_ASSERT;
+/*
+	TIccStatus Status=ICC_ERROR;
+	TIccGlobals * pIccReader;
+
+
+	if ((Status=GetReaderFromSessionId(xSessionId,
+									   &pIccReader)) 
+		!= ICC_NO_ERROR){
+		esyslog("ERROR iccSmartcardReset:  invalid sessionId !!!");
+		goto End;
+	}
+	
+	switch (xMode){
+	case ICC_ACCESS_NONE:
+		pIccReader->accessMode=xMode;
+		Status= ICC_NO_ERROR;
+		break;
+	case ICC_ACCESS_EXCLUSIVE:
+		pIccReader->accessMode=xMode;
+		Status= ICC_NO_ERROR;
+		break;
+	default:
+		Status= ICC_ERROR_MODE;
+		break;
+	}
+
+ End:
+	return Status;
+*/
+}
+
diff --git a/mcu/driver/drv/src/bf.c b/mcu/driver/drv/src/bf.c
new file mode 100644
index 0000000..4b920a2
--- /dev/null
+++ b/mcu/driver/drv/src/bf.c
@@ -0,0 +1,483 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    bf.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   This Module defines the ring-buffer API
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#include "drv_comm.h"
+#include "bmd.h"
+
+
+/*
+* FUNCTION                                                            
+*	Buff_init
+*
+* DESCRIPTION                                                           
+*   	This function is to let a memory area become a ring-buffer
+*
+* CALLS  
+*
+* PARAMETERS
+*	*Buf: struct of BUFFER_INFO
+*	Buffaddr: the start addr of memory area
+*	uTotalSize: the size of the memory area
+*	
+* RETURNS
+*	None
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+void Buff_init(BUFFER_INFO *Buf,kal_uint8 *Buffaddr, kal_uint16 uTotalSize)
+{	
+	Buf->Read = 0;
+	Buf->Write = 0;
+	Buf->Length = uTotalSize;
+	Buf->CharBuffer = Buffaddr;
+}
+
+/*
+* FUNCTION                                                            
+*	Buff_Push
+*
+* DESCRIPTION                                                           
+*   	This function is to put a data to ring-buffer
+*
+* CALLS  
+*
+* PARAMETERS
+*	*Buf: struct of BUFFER_INFO
+*	*pushData: the data will be put into ring-buffer
+*	
+* RETURNS
+*	None
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+void Buff_Push(BUFFER_INFO *Buf,kal_uint8 *pushData)
+{
+	*BuffWrite(Buf) = *pushData;	
+	BWrite(Buf)++;
+	if (BWrite(Buf) >= BLength(Buf))
+	{
+		BWrite(Buf) -= BLength(Buf);
+	}
+}
+
+/*
+* FUNCTION                                                            
+*	Buff_Pop
+*
+* DESCRIPTION                                                           
+*   	This function is to pop a data from ring-buffer
+*
+* CALLS  
+*
+* PARAMETERS
+*	*Buf: struct of BUFFER_INFO
+*	*popData: the data will be pop from ring-buffer
+*	
+* RETURNS
+*	None
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+void Buff_Pop(BUFFER_INFO *Buf,kal_uint8 *popData)
+{
+	*popData= *BuffRead(Buf);
+	BRead(Buf)++;
+	if (BRead(Buf) >= BLength(Buf))
+	{
+		BRead(Buf) -= BLength(Buf);
+	}
+
+}
+
+void Buff_look(BUFFER_INFO *Buf,kal_uint8 *popData,kal_uint8 num)
+{
+   kal_uint8 index;
+   kal_uint16 tmp;
+   
+   tmp = BRead(Buf);
+   for(index=0;index<num;index++)
+   {
+	   *popData= *(Buf->CharBuffer+tmp);
+	   
+	   tmp++;
+	   if (tmp >= BLength(Buf))
+	   {
+		   tmp -= BLength(Buf);
+	   }
+	}
+}
+/*
+* FUNCTION                                                            
+*	Buff_IsEmpty
+*
+* DESCRIPTION                                                           
+*   	This function is check whether ring-buffer is empty
+*
+* CALLS  
+*
+* PARAMETERS
+*	*Buf: struct of BUFFER_INFO
+*	
+* RETURNS
+*	None
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+kal_uint8 Buff_IsEmpty(BUFFER_INFO *Buf)
+{
+	kal_uint8 status;
+	if ( BRead(Buf) == BWrite(Buf) ) 
+	{
+		status = Buff_isEmpty;
+	}
+	else
+	{
+		status = Buff_notEmpty;
+	}
+	return status;
+}
+
+/*
+* FUNCTION                                                            
+*	Buff_IsFull
+*
+* DESCRIPTION                                                           
+*   	This function is check whether ring-buffer is full
+*
+* CALLS  
+*
+* PARAMETERS
+*	*Buf: struct of BUFFER_INFO
+*	
+* RETURNS
+*	None
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+kal_uint8 Buff_IsFull (BUFFER_INFO *Buf)
+{
+	kal_uint8 status;
+	kal_uint16 tmp = BRead(Buf);
+	if (tmp == 0)
+		tmp = BLength(Buf);
+
+	if ( (tmp-BWrite(Buf)) == 1)
+	{
+		status = Buff_isFull;
+	}
+	else
+	{
+		status = Buff_notFull;
+	}
+	return status;
+}
+
+/*
+* FUNCTION                                                            
+*	Buff_GetRoomLeft
+*
+* DESCRIPTION                                                           
+*   	This function is obtain the size of the residual space 
+*	in ring-buffer
+*
+* CALLS  
+*
+* PARAMETERS
+*	*Buf: struct of BUFFER_INFO
+*	
+* RETURNS
+*	the size of the residual space 
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+kal_uint16 Buff_GetRoomLeft (BUFFER_INFO *Buf)
+{
+	kal_uint16	RoomLeft = 0;
+	if ( BRead(Buf) <= BWrite(Buf) ) 
+	{
+                RoomLeft = BLength(Buf) - BWrite(Buf) + BRead(Buf) - 1;
+	}
+	else
+	{
+		RoomLeft = BRead(Buf) - BWrite(Buf) - 1;
+	}
+
+	return RoomLeft;
+}
+
+/*
+* FUNCTION                                                            
+*	Buff_GetBytesAvail
+*
+* DESCRIPTION                                                           
+*   	This function is obtain the size of the used space 
+*	in ring-buffer
+*
+* CALLS  
+*
+* PARAMETERS
+*	*Buf: struct of BUFFER_INFO
+*	
+* RETURNS
+*	the size of the used space
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+kal_uint16 Buff_GetBytesAvail (BUFFER_INFO *Buf)
+{
+	kal_uint16	BytesAvail = 0;
+	if (BWrite(Buf) >= BRead(Buf))
+		BytesAvail = BWrite(Buf) - BRead(Buf);
+	else 
+		BytesAvail = BLength(Buf) - BRead(Buf) + BWrite(Buf);	
+
+	return BytesAvail;
+}
+
+/*
+* FUNCTION                                                            
+*	Buff_GetLength
+*
+* DESCRIPTION                                                           
+*   	This function is to obtain the total size of the ring-buffer
+*
+* CALLS  
+*
+* PARAMETERS
+*	*Buf: struct of BUFFER_INFO
+*	
+* RETURNS
+*	the total size of the ring-buffer
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+kal_uint16 Buff_GetLength(BUFFER_INFO *Buf)
+{
+	return Buf->Length;
+}
+
+/*
+* FUNCTION                                                            
+*	Buff_Flush
+*
+* DESCRIPTION                                                           
+*   	This function is to reset the ring-buffer
+*
+* CALLS  
+*
+* PARAMETERS
+*	*Buf: struct of BUFFER_INFO
+*	
+* RETURNS
+*	None
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+void Buff_Flush (BUFFER_INFO *Buf)
+{
+	Buf->Write = Buf->Read = 0;
+}
+
+/*
+* FUNCTION                                                            
+*	Get32FromBuff
+*
+* DESCRIPTION                                                           
+*   	This function is to obtain a 32bit data from ringbuffer
+*
+* CALLS  
+*
+* PARAMETERS
+*	*Buf: struct of BUFFER_INFO
+*	*DATA: the data will be obtain from ringbuffer
+*	
+* RETURNS
+*	None
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+void Get32FromBuff(BUFFER_INFO *Buf,kal_uint32 *DATA)
+{
+	kal_uint8	tmp,index;
+	kal_uint32 	tmp32;
+	*DATA =0;
+	for (index =0;index < 4;index++)
+	{
+		Buff_Pop(Buf,&tmp);
+		tmp32 = (kal_uint32)tmp;
+		//(*DATA) |= (tmp32 << (24-8*index));
+		(*DATA) |= (tmp32 << (8*index));
+	}
+}
+
+/*
+* FUNCTION                                                            
+*	Put32toBuff
+*
+* DESCRIPTION                                                           
+*   	This function is to put a 32bit data to ringbuffer
+*
+* CALLS  
+*
+* PARAMETERS
+*	*Buf: struct of BUFFER_INFO
+*	*DATA: the data will be put into ringbuffer
+*	
+* RETURNS
+*	None
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+void Put32toBuff(BUFFER_INFO *Buf,kal_uint32 *DATA)
+{
+	kal_uint8	tmp,index;
+	kal_uint32 	tmp32;
+	for (index =0;index < 4;index++)
+	{
+		//tmp32 = ((*DATA) >> (24-8*index));
+		tmp32 = ((*DATA) >> (8*index));
+		tmp = (kal_uint8)tmp32;		
+		Buff_Push(Buf,&tmp);
+	}		
+}
+
+/*
+* FUNCTION                                                            
+*	MemCPY
+*
+* DESCRIPTION                                                           
+*   	This function is to copy memory block
+*
+* CALLS  
+*
+* PARAMETERS
+*	dst: destination address.
+*	src: source address.
+*	len: copy length
+*	
+* RETURNS
+*	None
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+void MemCPY(kal_uint8 *dst,kal_uint8 *src,kal_uint32 len)
+{
+	kal_uint32 index;
+	for (index = 0; index < len; index++) 
+		*dst++ = *src++;
+}
+
+/*
+* FUNCTION                                                            
+*	MemSET
+*
+* DESCRIPTION                                                           
+*   	This function is to set a value to a memory blcok
+*
+* CALLS  
+*
+* PARAMETERS
+*	dst: destination address.
+*	len: copy length
+*	data: the value
+*	
+* RETURNS
+*	None
+*
+* GLOBALS AFFECTED
+*   external_global
+*/
+void MemSET(kal_uint8 *dst,kal_uint8 data,kal_uint32 len)
+{
+	kal_uint32 index;
+	for (index = 0; index < len; index++) 
+		*dst++ = data;
+}
+
diff --git a/mcu/driver/drv/src/dcl_sim.c b/mcu/driver/drv/src/dcl_sim.c
new file mode 100644
index 0000000..cb16222
--- /dev/null
+++ b/mcu/driver/drv/src/dcl_sim.c
@@ -0,0 +1,550 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    dcl_sim.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *	This Module defines DCL (Driver Common Layer) of the SIM card driver.
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ * removed!
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#include "drv_features.h"
+#include "drv_comm.h"
+#include "dcl.h"
+#include "dma_sw.h"
+#include "sim_al.h"
+#include "sim_drv_HW_reg_MTK.h"
+#include "sim_drv_HW_def_MTK.h"
+#include "sim_drv_SW_struct.h"
+#include "sim_drv_SW_function.h"
+#include "sim_drv_SW_API.h"
+
+
+#include "intrCtrl.h"
+
+#include "cache_sw.h"
+#include "init.h"
+
+#ifdef DCL_SIM_INTERFACE
+
+#if !defined(DRV_SIM_OFF)
+/**************************************************************************
+following defines static global variables used in this file
+***************************************************************************/
+static kal_bool fgSIMInit = KAL_FALSE;
+static kal_semid dclSimArb;
+
+
+#define SIM_RESOURCE_HEAD 0x5a5a5a5a
+#define SIM_RESOURCE_TAIL 0xa5a5a5a5
+
+#define SIM_RSC_HANDLE_UDEF	0xffffffff
+
+typedef struct{
+	kal_uint32 guardHead;
+	kal_bool assigned;
+	kal_uint32 thdId;
+	kal_uint32 allocatedPoint;
+	DCL_SIMDriver_t *driver;
+	DCL_SIM_HW_CB driverHandle;
+	kal_uint32 guardTail;
+} DCL_SIM_RESOURCE;
+
+static DCL_SIM_RESOURCE	simResource[DCL_SIM_MAX_INTERFACE];
+
+/******************************************************************************************
+*following are extern variables from other file
+******************************************************************************************/
+extern sim_ctrlDriver sim_ctrlDriver_All;
+/***************************************************************************************
+followings are DCL SD API exported 
+*****************************************************************************************/
+/*************************************************************************
+* FUNCTION
+*  DclSD_Initialize
+*
+* DESCRIPTION
+* 	This function is to initialize the SD driver related resource.
+*	This function should be called in system initialization before tasks are scheduling.
+*
+* PARAMETERS
+*	N/A
+*
+* RETURNS
+*	STATUS_OK : this should be the only return value since MSDC_initialize returns nothing.
+*
+*************************************************************************/
+DCL_STATUS DclSIM_Initialize(void)
+{
+	kal_uint32	maskedValue;
+	kal_uint32	loopIndex;
+	
+	maskedValue = SaveAndSetIRQMask();
+	if(KAL_FALSE == fgSIMInit){
+		fgSIMInit = KAL_FALSE;
+		RestoreIRQMask(maskedValue);
+		kal_mem_set(simResource, 0, sizeof(DCL_SIM_RESOURCE) * DCL_SIM_MAX_INTERFACE);
+		dclSimArb = kal_create_sem("SIM_DCL", 1);
+		for(loopIndex = 0; DCL_SIM_MAX_INTERFACE > loopIndex; loopIndex ++){
+			simResource[loopIndex].guardHead = SIM_RESOURCE_HEAD;
+			simResource[loopIndex].guardTail = SIM_RESOURCE_TAIL;
+			simResource[loopIndex].driverHandle = SIM_RSC_HANDLE_UDEF;
+		}
+	}
+	else{
+		RestoreIRQMask(maskedValue);
+	}
+	
+	return STATUS_OK;
+}
+
+/*************************************************************************
+* FUNCTION
+*  DclSD_Initialize
+*
+* DESCRIPTION
+* 	This function is to get SD DCL handler.
+*
+* PARAMETERS
+*	eDev - only valid for DCL_SD.
+*	flags -following bit stand for specific meaning.
+*		DCL_SD_FLAGS_CARD1: to get a handle for card 1
+*		DCL_SD_FLAGS_CARD2: to get a handle for card 2
+*		DCL_SD_FLAGS_SIMPLUS: to get a handle for sim plus
+*		Other values are prohibited
+* RETURNS
+*  DCL_HANDLE_INVALID - Open failed.
+*  other value - a valid handle
+*
+*************************************************************************/
+DCL_HANDLE DclSIM_Open(DCL_DEV dev, DCL_FLAGS flags)
+{
+	kal_uint32 retAddr = 0;
+	kal_uint32 thdId;
+	kal_uint32 loopIndex;
+	
+	
+	if (dev != DCL_SIM)
+	{
+		ASSERT(0);
+		return DCL_HANDLE_INVALID;
+	}
+
+#if defined(__RVCT__)
+        /* RVCT doesn't support inline assemlber; bypass temporarily */
+        retAddr = 0;
+#else   /* __RVCT__ */
+        /* get the return address */
+        __asm {
+            MOV retAddr,lr
+        }
+#endif  /* __RVCT__ */
+	thdId = (kal_uint32)kal_get_current_thread_ID();
+
+
+	/*
+		In SIM DCL open, we only mark control block as assigned and return handle to user.
+		We don't support one resource used by multiple applications, so the control block will be not re-assigned.
+		Every time this function is called, we just find an unused control block, mark it assigned, and return the handle.
+	*/
+	
+	kal_take_sem(dclSimArb, 1);
+	for(loopIndex = 0; DCL_SIM_MAX_INTERFACE > loopIndex; loopIndex ++){
+		if (KAL_FALSE == simResource[loopIndex].assigned){
+			simResource[loopIndex].assigned = KAL_TRUE;
+			simResource[loopIndex].thdId = thdId;
+			simResource[loopIndex].allocatedPoint = retAddr;
+			kal_give_sem(dclSimArb);
+			return (DCL_HANDLE)(&simResource[loopIndex]);
+		}
+	}
+	kal_give_sem(dclSimArb);
+	return 0;
+}
+
+DCL_STATUS DclSIM_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+	ASSERT(0);
+	return 	STATUS_UNSUPPORTED;
+}
+DCL_STATUS DclSIM_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN *buf_len, DCL_OPTIONS options)
+{
+	ASSERT(0);
+	return 	STATUS_UNSUPPORTED;
+}
+
+/*************************************************************************
+* FUNCTION
+*  DclSIM_Configure
+*
+* DESCRIPTION
+* 	This function is to configure SIM interface. This is an important funciton since we rely on this function to hook correct function table.
+*
+* PARAMETERS
+*	handle - a valid handle return by DclSIM_Open()
+*	configure - a ponter to SIM_CONFIG_T structure which is a member of union 
+*              DCL_CONFIGURE_T.
+* RETURNS
+*	STATUS_OK - the configuration is done correctly.
+*  	STATUS_INVALID_HANDLE - It's a invalid handle.
+*  	STATUS_NOT_OPENED - The module has not been opened.
+*  	STATUS_INVALID_CONFIGURATION - the configuration is not valid.
+*
+*************************************************************************/
+DCL_STATUS DclSIM_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
+{
+	SIM_CONFIG_T *prConfg;
+	DCL_SIM_RESOURCE *resource;
+	DCL_STATUS status;
+
+	/*check the handle*/
+	if(0 == handle)
+		ASSERT(0);
+	resource = (DCL_SIM_RESOURCE *)handle;
+	if(SIM_RESOURCE_HEAD != resource->guardHead || SIM_RESOURCE_TAIL != resource->guardTail)
+		ASSERT(0);
+
+	/*state check*/
+	if (SIM_RSC_HANDLE_UDEF != resource->driverHandle || NULL != resource->driver)
+		ASSERT(0);
+
+	/*configure to use sim_ctrlDriver_Single for single SIM platform*/
+	prConfg = (SIM_CONFIG_T *)configure;
+
+	switch(prConfg->apType){
+		case SIM_CONFIG_AP_TYPE_PHONE1:
+			resource->driver = (DCL_SIMDriver_t *)&sim_ctrlDriver_All;
+			/*driver handle will be the pointer to hw control block in the future, but before we finish SMD, we fix a workable uint32 here*/
+			resource->driverHandle = 0;
+			status = STATUS_OK;
+			break;
+		default:
+			ASSERT(0);
+			status = STATUS_INVALID_CONFIGURATION;
+			break;
+	}
+
+	return status;
+}
+DCL_STATUS DclSIM_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
+{
+	ASSERT(0);
+	return 	STATUS_UNSUPPORTED;
+}
+
+typedef DCL_STATUS (*DCL_SIM_CTRL_API) (DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data);
+
+DCL_STATUS DCL_SIM_CTRL_API_RST(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	DCL_SIM_STATUS status;
+	SIM_CTRL_RST_T *prRst;
+	DCL_SIM_RESOURCE *resource;
+
+	/*check the handle*/
+	if(0 == handle)
+		ASSERT(0);
+	resource = (DCL_SIM_RESOURCE *)handle;
+	if(SIM_RESOURCE_HEAD != resource->guardHead || SIM_RESOURCE_TAIL != resource->guardTail)
+		ASSERT(0);
+
+	/*state check*/
+	if (SIM_RSC_HANDLE_UDEF == resource->driverHandle)
+		ASSERT(0);
+	
+	prRst = &(data->rSIMRst);
+	status = resource->driver->rst(prRst->ExpectVolt, prRst->ResultVolt, prRst->warm, resource->driverHandle);
+	prRst->rstResult = status;
+	
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SIM_CTRL_API_CMD(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	kal_uint32 status;
+	SIM_CTRL_CMD_T *prCmd;
+	DCL_SIM_RESOURCE *resource;
+
+	/*check the handle*/
+	if(0 == handle)
+		ASSERT(0);
+	resource = (DCL_SIM_RESOURCE *)handle;
+	if(SIM_RESOURCE_HEAD != resource->guardHead || SIM_RESOURCE_TAIL != resource->guardTail)
+		ASSERT(0);
+
+	/*state check*/
+	if (SIM_RSC_HANDLE_UDEF == resource->driverHandle)
+		ASSERT(0);
+	
+	prCmd = &(data->rSIMCmd);
+	status = resource->driver->cmd(prCmd->txData, prCmd->txSize, prCmd->rxData, prCmd->rxSize, resource->driverHandle);
+	*prCmd->statusWord = status;
+		
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SIM_CTRL_API_PWOFF(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	DCL_SIM_RESOURCE *resource;
+
+	/*check the handle*/
+	if(0 == handle)
+		ASSERT(0);
+	resource = (DCL_SIM_RESOURCE *)handle;
+	if(SIM_RESOURCE_HEAD != resource->guardHead || SIM_RESOURCE_TAIL != resource->guardTail)
+		ASSERT(0);
+
+	/*state check*/
+	if (SIM_RSC_HANDLE_UDEF == resource->driverHandle)
+		ASSERT(0);
+	
+	resource->driver->pwOff(resource->driverHandle);
+	
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SIM_CTRL_API_GET_CARD_INFO(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	SIM_CTRL_GET_CARD_INFO_T *prInfo;
+	DCL_SIM_RESOURCE *resource;
+
+	/*check the handle*/
+	if(0 == handle)
+		ASSERT(0);
+	resource = (DCL_SIM_RESOURCE *)handle;
+	if(SIM_RESOURCE_HEAD != resource->guardHead || SIM_RESOURCE_TAIL != resource->guardTail)
+		ASSERT(0);
+
+	/*state check*/
+	if (SIM_RSC_HANDLE_UDEF == resource->driverHandle)
+		ASSERT(0);
+	
+	prInfo = &(data->rSIMGetCardInfo);
+	resource->driver->getCardInfo(prInfo->info, resource->driverHandle);
+	
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SIM_CTRL_API_SET_SPEED(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	SIM_CTRL_SET_MAX_SPEED_T *prSetSpeed;
+	DCL_SIM_RESOURCE *resource;
+
+	/*check the handle*/
+	if(0 == handle)
+		ASSERT(0);
+	resource = (DCL_SIM_RESOURCE *)handle;
+	if(SIM_RESOURCE_HEAD != resource->guardHead || SIM_RESOURCE_TAIL != resource->guardTail)
+		ASSERT(0);
+
+	/*state check*/
+	if (SIM_RSC_HANDLE_UDEF == resource->driverHandle)
+		ASSERT(0);
+	
+	prSetSpeed = &(data->rSIMSetMaxSpeed);
+	resource->driver->setSpeed(prSetSpeed->speed, resource->driverHandle);
+	
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SIM_CTRL_API_SET_PREFER_PROTOCOL(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	SIM_CTRL_SET_PREFER_PROTOCOL_T *prSetT;
+	DCL_SIM_RESOURCE *resource;
+
+	/*check the handle*/
+	if(0 == handle)
+		ASSERT(0);
+	resource = (DCL_SIM_RESOURCE *)handle;
+	if(SIM_RESOURCE_HEAD != resource->guardHead || SIM_RESOURCE_TAIL != resource->guardTail)
+		ASSERT(0);
+
+	/*state check*/
+	if (SIM_RSC_HANDLE_UDEF == resource->driverHandle)
+		ASSERT(0);
+	
+	prSetT = &(data->rSIMSetPreferProtocol);
+	resource->driver->setPreferT(prSetT->T, resource->driverHandle);
+	
+	return STATUS_OK;
+}
+
+DCL_STATUS DCL_SIM_CTRL_API_SET_CLK_STOP_MODE(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	SIM_CTRL_SET_CLK_STOP_MODE_T *prSetClkStop;
+	DCL_SIM_RESOURCE *resource;
+
+	/*check the handle*/
+	if(0 == handle)
+		ASSERT(0);
+	resource = (DCL_SIM_RESOURCE *)handle;
+	if(SIM_RESOURCE_HEAD != resource->guardHead || SIM_RESOURCE_TAIL != resource->guardTail)
+		ASSERT(0);
+
+	/*state check*/
+	if (SIM_RSC_HANDLE_UDEF == resource->driverHandle)
+		ASSERT(0);
+	
+	prSetClkStop = &(data->rSIMSetClkStopMode);
+	resource->driver->setClockStopMode(prSetClkStop->mode, resource->driverHandle);
+	
+	return STATUS_OK;
+}
+
+DCL_SIM_CTRL_API	DclSIM_APITbl[] = 
+{
+	DCL_SIM_CTRL_API_RST,
+	DCL_SIM_CTRL_API_CMD,
+	DCL_SIM_CTRL_API_PWOFF,
+	DCL_SIM_CTRL_API_GET_CARD_INFO,
+	DCL_SIM_CTRL_API_SET_SPEED,
+	DCL_SIM_CTRL_API_SET_PREFER_PROTOCOL,
+	DCL_SIM_CTRL_API_SET_CLK_STOP_MODE,
+};
+
+
+DCL_STATUS DclSIM_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	DCL_STATUS status;
+
+	/*dispatch*/
+	if(SIM_CTRL_CMD_DUMMY_END > cmd){
+		status = DclSIM_APITbl[cmd](handle, cmd, data);
+	}
+	else{
+		ASSERT(0);
+		status = STATUS_INVALID_CMD;
+	}
+	
+
+
+	return status;	
+}
+#else /*!defined(DRV_SIM_OFF)*/
+
+
+DCL_STATUS DclSIM_Initialize(void)
+{
+	return STATUS_FAIL;
+}
+
+DCL_HANDLE DclSIM_Open(DCL_DEV dev, DCL_FLAGS flags)
+{
+   return DCL_HANDLE_INVALID;
+}
+
+DCL_STATUS DclSIM_ReadData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
+{
+	return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSIM_WriteData(DCL_HANDLE handle, DCL_BUFF *buff, DCL_BUFF_LEN buf_len, DCL_OPTIONS options)
+{
+	return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSIM_Configure(DCL_HANDLE handle, DCL_CONFIGURE_T *configure)
+{
+	return STATUS_UNSUPPORTED;
+}
+
+DCL_STATUS DclSIM_RegisterCallback(DCL_HANDLE handle, DCL_EVENT event, PFN_DCL_CALLBACK callback)
+{
+	return STATUS_FAIL;
+}
+
+DCL_STATUS DclSIM_Control(DCL_HANDLE handle, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data)
+{
+	return STATUS_FAIL;
+}
+
+DCL_STATUS DclSIM_Close(DCL_HANDLE handle)
+{
+	return STATUS_FAIL;
+}
+
+#endif /*!defined(DRV_SIM_OFF)*/
+
+#endif /*DCL_SIM_INTERFACE*/
diff --git a/mcu/driver/drv/src/e_compass_main.c b/mcu/driver/drv/src/e_compass_main.c
new file mode 100644
index 0000000..32f6443
--- /dev/null
+++ b/mcu/driver/drv/src/e_compass_main.c
@@ -0,0 +1,173 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    e_compass_main.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   This Module defines a task to provide e_compass driver interface
+ *
+ * Author:
+ * Peter Zhang
+ *
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#include "drv_comm.h"
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"
+#include "syscomp_config.h"   
+#if defined (__E_COMPASS_SENSOR_SUPPORT__)
+#include "kal_public_api.h"
+#include "stacklib.h"           /* Basic type for dll, evshed, stacktimer */
+#include "event_shed.h"         /* Event scheduler */
+#include "task_config.h"        /* Task creation */
+#include "e_compass_sensor.h"
+
+extern E_CompassSensorStruct e_compass_sensor_data;
+
+/*************************************************************************
+* Function declaration
+ *************************************************************************/
+kal_bool    ec_task_create(comptask_handler_struct **handle);
+
+static void ec_task_main(task_entry_struct *task_entry_ptr);
+static kal_bool   ec_task_reset(void);
+static kal_bool   ec_task_end(void);
+
+/*************************************************************************
+* FUNCTION
+*   ec_task_create
+*
+* DESCRIPTION
+*   This function implements xyz entity's create handler.
+*
+* PARAMETERS
+*
+* RETURNS
+*   None
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool
+ec_task_create(comptask_handler_struct **handle)
+{
+    static const comptask_handler_struct ec_handler_info =
+    {
+        ec_task_main,       /* task entry function */
+        NULL,               /* task initialization function */
+        ec_task_reset       /* task reset handler */
+       
+    };
+
+    *handle = (comptask_handler_struct *)&ec_handler_info;
+    return KAL_TRUE;
+}
+
+/*************************************************************************
+* FUNCTION
+*   ec_task_main
+*
+* DESCRIPTION
+*   This function implements xyz task's entry function
+*
+* PARAMETERS
+*
+* RETURNS
+*   None
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+void ec_task_main( task_entry_struct * task_entry_ptr )
+{	
+    kal_uint32 event_group;
+    /*initialize function*/
+    if (e_compass_sensor_data.event == NULL)
+      e_compass_sensor_data.event = kal_create_event_group("ECEVT");
+    e_compass_init();
+
+    while (1) 
+    {
+        kal_retrieve_eg_events(e_compass_sensor_data.event,1,KAL_OR_CONSUME,&event_group,KAL_SUSPEND);
+        e_compass_main_hdr();
+    }
+
+    /* Do component task's processing here */
+}
+
+/*************************************************************************
+* FUNCTION
+*	ec_task_reset
+*
+* DESCRIPTION
+*	This function implements xyz's reset handler
+*
+* PARAMETERS
+*	task_index	-	task's index
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+kal_bool
+ec_task_reset(void)
+{
+    /* Do task's reset here.
+     * Notice that: shouldn't execute modules reset handler since
+     * stack_task_reset() will do. */
+    return KAL_TRUE;
+}
+
+#endif
diff --git a/mcu/driver/drv/src/e_compass_sensor.c b/mcu/driver/drv/src/e_compass_sensor.c
new file mode 100644
index 0000000..2040bd7
--- /dev/null
+++ b/mcu/driver/drv/src/e_compass_sensor.c
@@ -0,0 +1,708 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2005
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    e_compass_sensor.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   This Module is for e_compass sensor driver.
+ *
+ * Author:
+ * Peter Zhang
+ *
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+//MSBB remove #include "custom_config.h"
+#include "gpio_sw.h"
+#include "drv_comm.h"
+#include "svc_sap.h"
+#include "nvram_msgid.h"
+#if defined (__E_COMPASS_SENSOR_SUPPORT__)
+#include "kal_public_defs.h" //MSBB change #include "stack_common.h"
+#include "syscomp_config.h" /*MOD_EC_TASK*/
+#include "stacklib.h"       /* Basic type for dll, evshed, stacktimer */
+#include "event_shed.h"     /* Event scheduler */
+#include "stack_timer.h"    /*Timer*/
+//MSBB remove #include "app_buff_alloc.h" /*buffer*/
+#include "task_config.h"    /* Task creation */
+#include "e_compass_sensor.h"
+#include "e_compass_sensor_custom.h"
+#include "e_compass_sensor_buff.h"
+#include "gpt_sw.h"
+
+#include "nvram_struct.h"
+#include "nvram_enums.h"
+#include "nvram_data_items.h"
+#include "nvram_editor_data_item.h"
+#include "nvram.h"
+#include "nvram_interface.h"
+
+#include "drv_trc.h"
+
+/*Variable Declaration*/
+E_CompassSensorStruct e_compass_sensor_data;
+E_CompassSensorBufferStruct e_compass_sensor_buff;
+E_CompassSensor_customize_function_struct *e_compass_sensor_custom_fp;
+E_CompassSensor_custom_data_struct *e_compass_sensor_custom_dp;
+
+static kal_timerid  e_compass_power_on_timer_id = 0;
+static kal_bool is_e_compass_enabled = KAL_FALSE;
+static kal_bool nvram_cali_result = KAL_FALSE;
+/* we use it to keep latest calibrated data */
+static E_CompassSensorCalibratedDataStruct e_compass_calibrated_data;
+
+/* middleware output should not exceed max value */
+#define E_COMPASS_SENSOR_OUTPUT_MAX         360
+
+/* local function declare */
+static void e_compass_sensor_power_on_callback(void *timer_param);
+static void e_compass_enable_driver(kal_bool enable);
+static void e_compass_write_nvram(E_CompassSensorCalibratedDataStruct *calibrated_data);
+
+/* GPT timer callback */
+void e_compass_sample_cb(void *parameter)
+{
+    kal_set_eg_events(e_compass_sensor_data.event,1,KAL_OR);
+}
+
+/*E_Compass main function*/
+/*
+* FUNCTION                                                            
+*   e_compass_start_cali
+*
+* DESCRIPTION                                                           
+*       This function is to start calibration
+*
+* CALLS  
+*
+* PARAMETERS
+*   None
+*	
+* RETURNS
+*   None
+*/
+void e_compass_sensor_start_cali(void)
+{
+    drv_trace0(TRACE_GROUP_10, EC_CALIBRATION_START);
+    e_compass_enable_driver(KAL_FALSE);
+    e_compass_sensor_data.cali_state = E_COMPASS_SENSOR_START_CALI;
+    e_compass_enable_driver(KAL_TRUE);
+}
+
+/*
+* FUNCTION                                                            
+*   e_compass_sensor_cancel_cali
+*
+* DESCRIPTION                                                           
+*       This function is to cancel calibration
+*
+* CALLS  
+*
+* PARAMETERS
+*   None
+*	
+* RETURNS
+*   None
+*/
+void e_compass_sensor_cancel_cali(void)
+{
+    drv_trace0(TRACE_GROUP_10, EC_CALIBRATION_ABORT);
+    e_compass_enable_driver(KAL_FALSE);
+    /* end user cancel calibration */
+    if (E_COMPASS_SENSOR_START_CALI == e_compass_sensor_data.cali_state)
+    {
+        /* calibration is on-going, we can cancel */
+        e_compass_sensor_data.cali_state = E_COMPASS_SENSOR_CALI_ABORTED;
+    }
+    /* else we do nothing. Driver might have finished calibration */
+
+    e_compass_enable_driver(KAL_TRUE);
+} 
+
+/*
+* FUNCTION                                                            
+*   e_compass_sensor_init
+*
+* DESCRIPTION                                                           
+*       This function is to initialize e_compass sensor driver
+*
+* CALLS  
+*
+* PARAMETERS
+*   None
+*	
+* RETURNS
+*   None
+*/
+void e_compass_init(void)
+{
+    /*get customization functin data and function pointr*/
+    e_compass_sensor_custom_fp = ec_GetFunc();
+    e_compass_sensor_custom_fp->ec_custom_init();
+    e_compass_sensor_custom_dp=e_compass_sensor_custom_fp->ec_get_data();
+
+    /* init calibration state and GPT handle for sample and calibration */
+    e_compass_sensor_data.cali_state = E_COMPASS_SENSOR_CALI_NONE;
+    GPTI_GetHandle(&(e_compass_sensor_data.sample_handle));
+
+    e_compass_flush_data_buffer();
+
+    e_compass_power_on_timer_id = kal_create_timer("E_Compass_Power_On_Timer");
+}
+     
+/*
+* FUNCTION                                                            
+*   e_compass_sensor_flush_buff
+*
+* DESCRIPTION                                                           
+*       This function is to flush data buffer
+*
+* CALLS  
+*
+* PARAMETERS
+*   None
+*	
+* RETURNS
+*   None
+*/
+/* void e_compass_sensor_flush_buff(void)
+{
+    e_compass_flush_data_buffer();   
+} */
+
+/*
+* FUNCTION                                                            
+*   e_compass_sensor_data_cb_registration
+*
+* DESCRIPTION                                                           
+*       This function is to register callback function for new data
+*
+* CALLS  
+*
+* PARAMETERS
+*   cb_fun:callback function 
+*   para: parameter of callback function
+*
+* RETURNS
+*   None
+*/
+void e_compass_sensor_data_cb_registration(EC_DATA_FUNC cb_fun,void *para)
+{
+    e_compass_sensor_data.data_cb_func = cb_fun;
+    e_compass_sensor_data.data_para = para;
+}   
+
+/*
+* FUNCTION                                                            
+*   e_compass_sensor_cali_cb_registration
+*
+* DESCRIPTION                                                           
+*       This function is to register callback function for calibration
+*
+* CALLS  
+*
+* PARAMETERS
+*   cb_fun:callback function 
+*   para: parameter of callback function
+*
+* RETURNS
+*   None
+*/
+void e_compass_sensor_cali_cb_registration(EC_CALI_FUNC cb_fun,void *para)
+{
+    e_compass_sensor_data.cali_cb_func = cb_fun;
+    e_compass_sensor_data.cali_para = para;
+}   
+
+#if defined (E_COMPASS_MAGNETIC_DETECT)
+/*
+* FUNCTION                                                            
+*   e_compass_sensor_mag_cb_registration
+*
+* DESCRIPTION                                                           
+*       This function is to register callback function for magnetic detection
+*
+* CALLS  
+*
+* PARAMETERS
+*   cb_fun:callback function 
+*   para: parameter of callback function
+*
+* RETURNS
+*   None
+*/
+void e_compass_sensor_mag_cb_registration(EC_MAG_FUNC cb_fun,void *para)
+{
+    e_compass_sensor_data.mag_cb_func = cb_fun;
+    e_compass_sensor_data.mag_para = para;
+}   
+#endif /* E_COMPASS_MAGNETIC_DETECT */
+
+/*
+* FUNCTION                                                            
+*   e_compass_sensor_get_data
+*
+* DESCRIPTION                                                           
+*       This function is to get converted data
+*
+* CALLS  
+*
+* PARAMETERS
+*   e_compass_data: data pointer
+*	
+* RETURNS
+*   result
+*/
+kal_bool e_compass_sensor_get_data(E_CompassSensorDataStruct *e_compass_data)
+{
+    kal_bool result;
+    kal_uint16 avail_data_size;
+
+    /* disable sample firstly */
+    e_compass_enable_driver(KAL_FALSE);
+
+    ec_get_buf_avail(avail_data_size);
+    if (0 != avail_data_size)
+    {
+        e_compass_pop_data_from_buffer(*e_compass_data);
+        result = KAL_TRUE;
+    }
+    else
+    {
+        result = KAL_FALSE;
+    }
+
+    /* enable sample again */
+    e_compass_enable_driver(KAL_TRUE);
+
+    return result;
+}
+
+/*
+* FUNCTION                                                            
+*   e_compass_get_calibration_result
+*
+* DESCRIPTION                                                           
+*       This function is to get previous calibration result
+*
+* CALLS  
+*
+* PARAMETERS
+*   None
+*	
+* RETURNS
+*   previous calibration result
+*/
+kal_bool e_compass_get_calibration_result(void)
+{
+    return nvram_cali_result;
+}
+
+/*
+* FUNCTION                                                            
+*   e_compass_nvram_init
+*
+* DESCRIPTION                                                           
+*       This function is to read calibrated data from NvRAM
+*
+* CALLS  
+*
+* PARAMETERS
+*   None
+*	
+* RETURNS
+*   None
+*/
+void e_compass_nvram_init(void)
+{
+    static kal_bool is_e_compass_nvram_init = KAL_FALSE;
+    nvram_ef_ecompass_calibration ec_nvram;
+
+    if (KAL_FALSE == is_e_compass_nvram_init)
+    {
+        /* read data from NvRAM */
+        nvram_external_read_data(NVRAM_EF_ECOMPASS_DATA_LID, 1, (kal_uint8 *)&ec_nvram, sizeof(nvram_ef_ecompass_calibration));
+        /* E_COMPASS_DEBUG_OUTPUT("Read from NvRAM usr_moffset_x = %d, usr_moffset_y = %d, usr_moffset_z = %d, misc = %d", ec_nvram.usr_moffset_x, ec_nvram.usr_moffset_y, ec_nvram.usr_moffset_z, 0); */
+        drv_trace4(TRACE_GROUP_10, EC_NVRAM_READBACK, ec_nvram.usr_moffset_x, ec_nvram.usr_moffset_y, ec_nvram.usr_moffset_z, ec_nvram.cali_result);
+
+        e_compass_calibrated_data.usr_moffset_x = ec_nvram.usr_moffset_x;
+        e_compass_calibrated_data.usr_moffset_y = ec_nvram.usr_moffset_y;
+        e_compass_calibrated_data.usr_moffset_z = ec_nvram.usr_moffset_z;
+        e_compass_calibrated_data.cali_result   = ec_nvram.cali_result;
+
+        e_compass_calibrated_data.x_axis_sensitivity = ec_nvram.x_axis_sensitivity;
+        e_compass_calibrated_data.y_axis_sensitivity = ec_nvram.y_axis_sensitivity;
+        e_compass_calibrated_data.x_max              = ec_nvram.x_max;
+        e_compass_calibrated_data.y_max              = ec_nvram.y_max;
+        e_compass_calibrated_data.x_min              = ec_nvram.x_min;
+        e_compass_calibrated_data.y_min              = ec_nvram.y_min;
+
+        nvram_cali_result                       = ec_nvram.cali_result;
+
+        /* we just read NvRAM once */
+        is_e_compass_nvram_init = KAL_TRUE;
+    }
+}
+
+/*************************************************************************
+* FUNCTION
+*   e_compass_sensor_power_on
+*
+* DESCRIPTION
+*   This function is to turn on sensor
+*
+* PARAMETERS
+*   None
+*
+* RETURNS
+*   None
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+void e_compass_sensor_power_on(void)
+{
+    static kal_bool is_middleware_init = KAL_FALSE;
+
+    drv_trace0(TRACE_GROUP_10, EC_CALIBRATION_POWERON);
+
+    if (KAL_FALSE == is_middleware_init)
+    {
+        /* we just need to initialize middleware once */
+        e_compass_sensor_custom_fp->ec_init_calibrated_data(&e_compass_calibrated_data);
+        is_middleware_init = KAL_TRUE;
+    }
+
+    e_compass_sensor_custom_fp->ec_turn_on(1);
+    /* we start timer, after timer expired, it will invoke e_compass_sensor_power_on_callback
+       because sensor need some time to be ready after power on */
+    kal_set_timer(e_compass_power_on_timer_id,(kal_timer_func_ptr)e_compass_sensor_power_on_callback,NULL,
+                  e_compass_sensor_custom_dp->poweron_delay,0);
+}
+
+/*for e_compass sensor power on */
+static void e_compass_sensor_power_on_callback(void *timer_param)
+{
+    e_compass_sensor_custom_fp->ec_turn_on(2);
+
+    /* enable E_Compass here after sensor and NvRAM are ready */
+    e_compass_enable(KAL_TRUE);
+}
+
+/*************************************************************************
+* FUNCTION
+*   e_compass_sensor_power_off
+*
+* DESCRIPTION
+*   This function is to turn off sensor
+*
+* PARAMETERS
+*   None
+*
+* RETURNS
+*   None
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+void e_compass_sensor_power_off(void)
+{
+    drv_trace0(TRACE_GROUP_10, EC_CALIBRATION_POWEROFF);
+    e_compass_enable(KAL_FALSE);
+    e_compass_sensor_custom_fp->ec_turn_off();
+}
+
+/*************************************************************************
+* FUNCTION
+*   e_compass_enable
+*
+* DESCRIPTION
+*   This function is to enable/disbale e_compass module.
+*
+* PARAMETERS
+*   None
+*
+* RETURNS
+*   None
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+void e_compass_enable(kal_bool enable)
+{
+    /* save flag, normally driver will not modify this flag. */
+    is_e_compass_enabled = enable;
+
+    e_compass_enable_driver(enable);
+}
+
+static void e_compass_enable_driver(kal_bool enable)
+{
+    if (KAL_TRUE == enable)
+    {
+        e_compass_sensor_custom_fp->ec_take_measurement();
+
+        /* we have different GPT timer for different state */
+        if (E_COMPASS_SENSOR_START_CALI != e_compass_sensor_data.cali_state)
+            GPTI_StartItem(e_compass_sensor_data.sample_handle,e_compass_sensor_custom_dp->normal_sample_dura,e_compass_sample_cb,NULL);
+        else
+            GPTI_StartItem(e_compass_sensor_data.sample_handle,e_compass_sensor_custom_dp->calibration_sample_dura,e_compass_sample_cb,NULL);
+    }
+    else
+    {
+        GPTI_StopItem(e_compass_sensor_data.sample_handle);
+    }
+}
+
+
+/*************************************************************************
+* FUNCTION
+*   e_compass_sensor_manual_init
+*
+* DESCRIPTION
+*   This function is to configure sensor middleware manually, end user must keep handset horizontal.
+*
+* PARAMETERS
+*   None
+*
+* RETURNS
+*   None
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+void e_compass_sensor_manual_init(void)
+{
+    drv_trace0(TRACE_GROUP_10, EC_MIDDLEWARE_MANUAL_INIT);
+    e_compass_enable_driver(KAL_FALSE);
+    /* sensor middleware init */
+    e_compass_sensor_custom_fp->ec_middleware_init();
+    e_compass_enable_driver(KAL_TRUE);
+}
+
+static void e_compass_write_nvram(E_CompassSensorCalibratedDataStruct *calibrated_data)
+{
+    ilm_struct *ec_ilm_ptr = 0;
+    void *parm_stream = 0;
+    void *data_stream = 0;
+    kal_uint16 pdu_len;
+    nvram_ef_ecompass_calibration ec_nvram;
+    module_type module_id;
+
+    module_id = MOD_EC_TASK;
+
+    /* for now we just save three fields */
+    ec_nvram.usr_moffset_x = calibrated_data->usr_moffset_x;
+    ec_nvram.usr_moffset_y = calibrated_data->usr_moffset_y;
+    ec_nvram.usr_moffset_z = calibrated_data->usr_moffset_z;
+    ec_nvram.cali_result   = calibrated_data->cali_result;
+
+    ec_nvram.x_axis_sensitivity = calibrated_data->x_axis_sensitivity;
+    ec_nvram.y_axis_sensitivity = calibrated_data->y_axis_sensitivity;
+    ec_nvram.x_max              = calibrated_data->x_max;
+    ec_nvram.y_max              = calibrated_data->y_max;
+    ec_nvram.x_min              = calibrated_data->x_min;
+    ec_nvram.y_min              = calibrated_data->y_min;
+
+    /* E_COMPASS_DEBUG_OUTPUT("Calibrated result usr_moffset_x = %d, usr_moffset_y = %d, usr_moffset_z = %d, misc = %d", ec_nvram.usr_moffset_x, ec_nvram.usr_moffset_y, ec_nvram.usr_moffset_z, 0); */
+    drv_trace4(TRACE_GROUP_10, EC_NVRAM_SAVE, ec_nvram.usr_moffset_x, ec_nvram.usr_moffset_y, ec_nvram.usr_moffset_z, ec_nvram.cali_result);
+
+    ec_ilm_ptr = allocate_ilm(module_id);
+    ec_ilm_ptr->msg_id = MSG_ID_NVRAM_WRITE_REQ;
+
+    parm_stream = construct_local_para(sizeof(nvram_write_req_struct), TD_CTRL);
+    data_stream = construct_peer_buff(sizeof(nvram_ef_ecompass_calibration), 0, 0, TD_CTRL);
+
+    ((nvram_write_req_struct*) parm_stream)->file_idx = NVRAM_EF_ECOMPASS_DATA_LID;
+    ((nvram_write_req_struct*) parm_stream)->para = 1;
+
+    pdu_len = sizeof(nvram_ef_ecompass_calibration);
+    kal_mem_cpy(get_pdu_ptr(data_stream, &pdu_len), (void*)&ec_nvram, sizeof(nvram_ef_ecompass_calibration));
+
+    ec_ilm_ptr->local_para_ptr = (local_para_struct*) parm_stream;
+    ec_ilm_ptr->peer_buff_ptr = (peer_buff_struct*) data_stream;
+
+    ec_ilm_ptr->src_mod_id  = module_id;
+    ec_ilm_ptr->dest_mod_id = MOD_NVRAM;
+    ec_ilm_ptr->sap_id = PS_NVRAM_SAP;
+    msg_send_ext_queue(ec_ilm_ptr);
+}
+
+/*************************************************************************
+* FUNCTION
+*   e_compass_main_hdr
+*
+* DESCRIPTION
+*   This function is to handle event.
+*
+* PARAMETERS
+*   None
+*
+* RETURNS
+*   None
+*
+* GLOBALS AFFECTED
+*
+*************************************************************************/
+void e_compass_main_hdr(void)
+{
+    kal_int16 x,y,z;
+    kal_uint16 room;
+    E_Compass_Sensor_Cali_enum cali_result;
+    E_CompassSensorDataStruct angle;
+#if defined (E_COMPASS_MAGNETIC_DETECT)
+    E_Compass_Sensor_Magnetic_State_enum mag_state;
+#endif /* E_COMPASS_MAGNETIC_DETECT */
+
+    /* disable example, maybe it is not necessary, GPT is one-shot, anyway it is harmless */
+    e_compass_enable_driver(KAL_FALSE);
+
+    /* read raw data */
+    e_compass_sensor_custom_fp->ec_read_adc(&x,&y,&z);
+    /* E_COMPASS_DEBUG_OUTPUT("Raw data X = %d, Y = %d, Z = %d, misc = %d", x, y, z, 0); */
+    drv_trace4(TRACE_GROUP_10, EC_RAW_DATA, x, y, z, 0);
+
+    switch (e_compass_sensor_data.cali_state)
+    {
+    case E_COMPASS_SENSOR_CALI_NONE:
+        /* normal case, we will convert raw data to angle */
+#if defined (__E_COMPASS_MIDDLEWARE_DEBUG__)
+        {
+            kal_int16 mag_x_dump;
+            kal_int16 mag_y_dump;
+            kal_int16 mag_z_dump;
+            e_compass_sensor_custom_fp->ec_middleware_dump(&mag_x_dump,&mag_y_dump,&mag_z_dump);
+            drv_trace4(TRACE_GROUP_10, EC_MIDDLEWARE_DUMP, mag_x_dump, mag_y_dump, mag_z_dump, 0);
+        }
+#endif  /* __E_COMPASS_MIDDLEWARE_DEBUG__ */
+
+        e_compass_sensor_custom_fp->ec_convert(x,y,z,&angle);
+        if (E_COMPASS_SENSOR_OUTPUT_MAX >= angle.angle)
+        {
+            e_compass_sensor_custom_fp->ec_get_calibrated_data(&e_compass_calibrated_data);
+            if (KAL_TRUE == e_compass_calibrated_data.cali_result)
+            {
+                /* save calibrated data into NvRAM */
+                e_compass_write_nvram(&e_compass_calibrated_data);
+            }
+
+            drv_trace1(TRACE_GROUP_10, EC_ATTITUDE_ANGLE, angle.angle);
+
+#if defined (E_COMPASS_MAGNETIC_DETECT)
+            /* we detect magnetic field here */
+            e_compass_sensor_custom_fp->ec_get_magnetic_data(&mag_state);
+            e_compass_sensor_data.mag_cb_func(e_compass_sensor_data.mag_para,mag_state);
+            drv_trace1(TRACE_GROUP_10, EC_MAGNETIC_STATE, mag_state);
+#endif /* E_COMPASS_MAGNETIC_DETECT */
+
+            ec_get_buf_roomleft(room);
+            if (0 != room)
+            {
+                e_compass_push_data_to_buffer(angle,room);
+            }
+            else
+            {
+                /* there is no room, if SW goes to here, that means something abnormal, MMI has not handled nofication for a long time
+                   we do nothing here */
+            }
+        }
+        break;
+
+    case E_COMPASS_SENSOR_START_CALI:
+        /* end user has started calibration */
+        cali_result = e_compass_sensor_custom_fp->ec_calibrate(x,y,z);
+        if (E_COMPASS_SENSOR_CALI_FINISHED == cali_result)
+        {
+            e_compass_sensor_custom_fp->ec_get_calibrated_data(&e_compass_calibrated_data);
+            if (KAL_TRUE == e_compass_calibrated_data.cali_result)
+            {
+                /* save calibrated data into NvRAM */
+                e_compass_write_nvram(&e_compass_calibrated_data);
+
+                /* calibration finished, we need to inform end user */
+                e_compass_sensor_data.cali_cb_func(e_compass_sensor_data.cali_para,E_COMPASS_SENSOR_CALI_SUCCESS);
+            }
+            else
+            {
+                /* calibration finished, we need to inform end user */
+                e_compass_sensor_data.cali_cb_func(e_compass_sensor_data.cali_para,E_COMPASS_SENSOR_CALI_FAILED);
+            }
+            drv_trace1(TRACE_GROUP_10, EC_CALIBRATION_RESULT, e_compass_calibrated_data.cali_result);
+            /* reset calibration state */
+            e_compass_sensor_data.cali_state = E_COMPASS_SENSOR_CALI_NONE;
+        }
+        break;
+
+    case E_COMPASS_SENSOR_CALI_ABORTED:
+        /* E_COMPASS_DEBUG_OUTPUT("Calibration aborted: %d %d %d %d", 0, 0, 0, 0); */
+        /* end user cancel calibration, we need to do something */
+        e_compass_sensor_custom_fp->ec_calibrate_cancel();
+
+        /* reset calibration state */
+        e_compass_sensor_data.cali_state = E_COMPASS_SENSOR_CALI_NONE;
+        break;
+
+    case E_COMPASS_SENSOR_CALI_FINISHED:
+    default:
+        /* we should not go to here, assert will happen */
+        ASSERT(0);
+    }
+
+    /* enable sample again, for the safe reason, if MMI has disabled it, however driver task still runs to here, we should double check */
+    if (KAL_TRUE == is_e_compass_enabled)
+        e_compass_enable_driver(KAL_TRUE);
+}
+
+#endif
diff --git a/mcu/driver/drv/src/fota_partial.c b/mcu/driver/drv/src/fota_partial.c
new file mode 100644
index 0000000..c7dd8a8
--- /dev/null
+++ b/mcu/driver/drv/src/fota_partial.c
@@ -0,0 +1,3405 @@
+/*****************************************************************************
+*  Copyright Statement:
+*  --------------------
+*  This software is protected by Copyright and the information contained
+*  herein is confidential. The software may not be copied and the information
+*  contained herein may not be used or disclosed except with the written
+*  permission of MediaTek Inc. (C) 2006
+*
+*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
+*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
+*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
+*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
+*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
+*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
+*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
+*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
+*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
+*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
+*
+*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
+*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
+*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
+*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
+*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. 
+*
+*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
+*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
+*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
+*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
+*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
+*
+*****************************************************************************/
+
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *   fota_partial.c
+ *
+ * Project:
+ * --------
+ *   Maui_Software
+ *
+ * Description:
+ * ------------
+ *   This file implement the function of FOTA firmware update downlaod 
+ *
+ * Author:
+ * -------
+ * -------
+ *
+ *============================================================================
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ * removed!
+ * removed!
+ * removed!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+/*******************************************
+*   Include File      
+********************************************/
+#if defined(__FOTA_DM__)
+
+#include "kal_general_types.h"
+#include "kal_debug.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include "fue_err.h"
+#include "fota.h"
+#include "flash_opt.h"
+#include "fat_fs.h"
+#include "custom_fota.h"
+#include "custom_img_config.h"
+#include "fue.h"
+#include "ssf_fue_support.h"
+#include "fue_update_support.h"
+#if defined(__MAUI_BASIC__)
+#include "uart_sw.h"
+#endif /* __MAUI_BASIC__ */
+#if defined(__HP_FOTA__)
+#include "Bitfone_update.h"
+#endif
+
+#include "dcl.h"
+
+#ifdef __EMMC_BOOTING__
+#include "fue_emmc_adapt.h"
+#endif
+
+#define _FUE_PKG_DEBUG_
+
+/*******************************************************************************
+ *   Global Function and Structure Definition
+ *******************************************************************************/
+
+FOTA_DATA FOTAData={STATUS_FOTA_NOT_INITIAL};
+
+FOTA_NFB_Update_Control    FOTA_Update_Ctrl;
+FOTA_Package_Control_st    FOTA_Package_Ctrl;
+
+#pragma arm section zidata = "NONCACHEDZI"
+
+kal_uint32  fota_temp_page_buffer[FOTA_FLASH_MAX_PAGE_SIZE];
+kal_uint32  fota_replace_page_buffer[FOTA_FLASH_MAX_PAGE_SIZE];
+
+#pragma arm section zidata
+
+/*******************************************************************************
+ *   Static Function and Structure Definition
+ *******************************************************************************/
+static kal_int32 FOTA_MTD_Read_Buffer(void *Buffer, kal_uint32 read_len);
+
+/* start address of update package reserved area */
+extern const kal_uint32 FOTA_PACKAGE_BASE_ADDRESS;
+
+/* Following functions and data varoables are located in FOTA library */
+extern FUE_ERROR_CODE FUE_InitializeUpdateRecord(kal_uint32 base_blk, kal_uint32 end_blk, \
+                                                 Flash_GAL_st *fgal, dbg_trace_func dbg_trace);
+extern FUE_ERROR_CODE FUE_NFB_Flush_Update_Record(FOTA_Custom_Update_Info* info_buffer, \
+                                                  dbg_trace_func dbg_trace);
+extern FUE_ERROR_CODE FUE_NFB_Get_Update_Record(FOTA_Custom_Update_Info* info_buffer,\
+                                                dbg_trace_func dbg_trace);
+
+extern FUE_ERROR_CODE FUE_NFB_Allocate_Block(kal_uint32 begin_block, kal_uint32 end_block, \
+                                             kal_uint32 curr_block, kal_uint32 *alloc_block, \
+                                             Flash_GAL_st *fgal, IsBlockAvailable_func check_available, \
+                                             dbg_trace_func dbg_trace);
+
+extern FUE_ERROR_CODE FUE_BlkInfo_Resume_Package_Blocks(FOTA_Package_Control_st *pkg_ctrl, \
+                                                        kal_uint32 *found_blocks, \
+                                                        /*FOTA_Package_Location_st *found_list, \*/
+                                                        FOTA_Package_List_st *found_list,\
+                                                        kal_uint32 *buff_ptr, \
+                                                        kal_uint32 *buff_len, \
+                                                        /*alloc_pkg_blk alloc_blk, \*/
+                                                        dbg_trace_func dbg_trace);
+
+extern kal_bool FUE_NFB_Is_Available_Block(kal_uint32 block_idx, kal_uint32* buff_ptr, Flash_GAL_st *fgal, \
+                                           dbg_trace_func dbg_trace);
+
+extern FUE_ERROR_CODE FUE_NFB_Replace_Current_Package_Block(FOTA_Package_Control_st *pkg_ctrl,\
+                                                            kal_uint32 *buff_ptr, \
+                                                            dbg_trace_func dbg_trace);
+
+extern FUE_ERROR_CODE FUE_NFB_Mark_Package_Block_Complete(FOTA_Package_Control_st *pkg_ctrl, \
+                                                          FOTA_Package_Info_st *pkg_info, dbg_trace_func dbg_trace);
+
+extern FUE_ERROR_CODE FUE_NFB_Allocate_PackageBlock(FOTA_Package_Control_st *pkg_ctrl, kal_uint32 start_block, \
+                                                    kal_uint32 *alloc_block, dbg_trace_func dbg_trace);
+
+extern FUE_ERROR_CODE FUE_NFB_Create_Package_Block(FOTA_Package_Control_st *pkg_ctrl, kal_uint32 block_index,\
+                                                   kal_uint32 last_block, kal_uint32 replace_block, \
+                                                   kal_bool add_session, dbg_trace_func dbg_trace);
+
+extern FUE_ERROR_CODE FUE_CreateInitialUpdateRecord(FOTA_NFB_Update_Control *update_ctrl, kal_uint32 start_block, \
+                                                    Flash_GAL_st *fgal, dbg_trace_func dbg_trace);
+
+extern FUE_ERROR_CODE FUE_BlkInfo_Is_Package_Block(FOTA_Package_Control_st *pkg_ctrl, kal_uint32 blk_num, dbg_trace_func dbg_trace);
+
+extern FUE_ERROR_CODE FUE_BlkInfo_Is_Update_Block(FOTA_NFB_Update_Control *update_ctrl, kal_uint32 blk_num, dbg_trace_func dbg_trace);
+
+extern kal_uint32 SSF_GetMAUIImageNumber(void);
+
+extern void FUE_Start_Download_State(void);
+
+extern void FUE_Start_Package_Verification_State(void);
+
+extern FOTA_Area_Info_Wrapper_st  FOTA_NFB_Area_Info;
+
+/* For update package block management */
+extern FOTA_Package_List_st g_fota_package_blocks[FOTA_PACKAGE_BLOCK_NUMBER];
+extern kal_uint32 FOTA_PKG_BLOCKS;
+
+/* Following functions are located in init.c */
+extern kal_uint32 INT_GetCurrentTime(void);
+
+
+/* the NFI access synchronization is implemented in NAND flash MTD layer */
+#define FOTA_LOCK()   
+#define FOTA_UNLOCK() 
+
+/* Forward declaration */
+Flash_GAL_st *FOTA_Setup_FGAL(void);
+static kal_int32 FOTA_MTD_Program_Buffer(void *Buffer, kal_uint32 write_len);
+
+kal_int32 FOTA_InitializeUpdateRecord(void);
+
+kal_int32 FOTA_InitializePackageReservoir(void);
+kal_int32 FOTA_FinishPackageBlock(void);
+kal_int32 FOTA_CheckAvailablePackageBlocks(kal_uint32 *available_num);
+kal_int32 FOTA_ClearPackageReservoir(void);
+kal_int32 FOTA_Get_TotalPackageBlock(kal_uint32 *pkg_blks, kal_uint32* pkg_pages);
+kal_int32 FOTA_Get_CurrentPackagePosition(kal_uint32 *curr_blks, kal_uint32* curr_pages);
+kal_int32 FOTA_ProgramPackagePage(void* buff, kal_uint32 *page_size);
+
+kal_int32 FOTA_GetPackageFlashInfo(kal_uint32 *blk_size, kal_uint32 *page_size);
+
+#if defined(__MAUI_BASIC__)
+
+
+#endif /*  __MAUI_BASIC__ */
+/*****************************************************************
+Description : dump trace via kal_print function.
+Input       : 
+Output      : None
+******************************************************************/
+kal_char  g_char_buff[512];
+void fue_dbg_print(kal_char* fmt, ...)
+{
+   va_list trace_p;
+   va_start(trace_p, fmt);
+   vsprintf(g_char_buff, fmt, trace_p);
+   va_end(trace_p);
+   kal_print(g_char_buff);
+#if defined(__MAUI_BASIC__)
+   if(KAL_FALSE == kal_query_systemInit())
+   {
+       while(!UART_CheckTxBufferEmpty(uart_port1)); /* wait for UART dump complete */
+   }
+#endif
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Package_Blk_Address
+DESCRIPTION
+   convert to block aligned address
+PARAMETER
+   NULL
+RETURN
+   INVALOD_DWORD : out of range
+--------------------------------------------------------------------------------- */
+kal_uint32 FOTA_Package_Blk_Address(FOTA_Package_Control_st *pkg_ctrl, kal_uint32 dst_addr)
+{
+   Logical_Flash_info_st  info;
+   kal_uint32             blk_idx      = 0;
+   kal_uint32             blk_addr     = 0;
+   kal_uint32             phy_blk      = 0;
+   kal_uint32             curr_blk_num = pkg_ctrl->m_fota_pkg_blocks;
+   Flash_GAL_st           *fgal        = pkg_ctrl->m_pkg_fgal;
+
+   ASSERT(fgal);
+
+   fgal->query_info(&info);
+   for(blk_idx = 0 ; blk_idx < curr_blk_num ; blk_idx++)
+   {
+      phy_blk = pkg_ctrl->m_fota_pkg_list[blk_idx].m_pkg_block_position;
+      blk_addr += (fgal->block_size(phy_blk)- 2*info.Flash_page_size);
+      if(blk_addr >= dst_addr)
+         break;
+   }
+   if( blk_idx == curr_blk_num )
+   {
+      fue_dbg_print("FOTA_Package_Blk_Idx: address:0x%x is beyond available %dblks!\n\r",
+                     dst_addr, curr_blk_num);
+      ASSERT(0);
+      return INVALID_DWORD;
+   }
+   else
+   {
+      if(blk_addr == dst_addr)
+         fue_dbg_print("FOTA_Package_Blk_Idx: address:0x%x is on the bounadry of blk:%d(%d)!\n\r",
+                        dst_addr, blk_idx, phy_blk);
+
+      return blk_addr;
+   }
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Initialize
+DESCRIPTION
+   FOTA Initialization API
+   1. Initialize data structure and progress initial step
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_Initialize(void)
+{
+   kal_int32              Ret;
+
+   if( STATUS_FOTA_INITIALIZED == FOTAData.Status )
+   {
+      return ERROR_FOTA_SUCCESS;
+   }
+
+   Ret = FOTA_InitializeUpdateRecord();
+   if( (ERROR_FOTA_NO_AVAILABLE_BLOCK == Ret) || (ERROR_FUE_OPERATION_STOP == Ret) ||
+       (ERROR_FUE_OVER_DESIGN == Ret) )
+      return Ret;
+   
+   Ret = FOTA_InitializePackageReservoir();
+
+   if(ERROR_FOTA_INVALID_PARAMETER == Ret)
+   {
+      return Ret;
+   }
+   fue_dbg_print("FOTA_Initialize: %d updatable images!\n\r", SSF_GetMAUIImageNumber());
+
+   FOTAData.SpareCurrWriteAddr = 0; 
+   FOTAData.SpareNextWriteBlockAddr = 0;
+   FOTAData.SpareCurrReadAddr = 0; 
+   FOTAData.SpareNextReadBlockAddr = 0;
+   FOTAData.BufferIndex = 0;
+   
+   if((Ret = FOTA_CustomInitialize()) < 0)
+      return Ret;
+   else
+      FOTAData.Status = STATUS_FOTA_INITIALIZED;
+   return ERROR_FOTA_SUCCESS;   
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_WriteData
+DESCRIPTION
+   FOTA write data API
+   1. This function is used to write data to spare image pool
+   2. This API only allow sequentially writing mechanism
+   3. Authentication mechanism is executed during writing
+PARAMETER
+   Length: the length of writing (Unit: Bytes)
+   Buffer: the start address of buffer
+RETURN
+   0: means pass write success (ERROR_FOTA_SUCCESS)
+   < 0: writing action is fail
+      ERROR_FOTA_AUTH_ROMINFO: authentication fail, can't find rom info
+      ERROR_FOTA_AUTH_FATBEGIN: authentication fail, fat begin address is different
+      ERROR_FOTA_AUTH_FATLEN: authentication fail, fat length is different
+      ERROR_FOTA_AUTH_HCHECKSUM: authentication fail, header checksum fail
+      ERROR_FOTA_AUTH_ID: authentication fail, platform id is different
+      ERROR_FOTA_AUTH_VERSION: authentication fail, downgrade is not allowed
+      ERROR_FOTA_AUTH_IMAGELEN: authentication fail, image length too large
+	 ERROR_FOTA_AUTH_FAIL: authentication fail before
+	 ERROR_FOTA_OVERRANGE: write over the spare image pool range
+	 ERROR_FOTA_NOT_INITIALIZED: not call FOTA_Initialize before
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_WriteData(kal_uint32 Length, void* Buffer)
+{
+   kal_int32  result;
+   kal_uint32 buff_addr = (kal_uint32)Buffer;
+   kal_uint8  *byte_ptr = NULL;
+
+   if (FOTAData.Status == STATUS_FOTA_NOT_INITIAL)
+      return ERROR_FOTA_NOT_INITIALIZED;
+
+   while(Length > 0)
+   {
+      if ((FOTAData.BufferIndex+Length)>=FOTA_BUFFER_SIZE)
+      {
+         /* no data in write buffer and user buffer is 4-byte aligned */
+         if( (FOTAData.BufferIndex == 0) && (0 == (buff_addr & 0x03)) ) 
+         {
+            result = FOTA_MTD_Program_Buffer((void*)buff_addr, FOTA_BUFFER_SIZE);
+         	  if (result < 0)
+               return result;
+            buff_addr += FOTA_BUFFER_SIZE;
+            Length -= FOTA_BUFFER_SIZE;
+         }
+         else
+         {
+            if(FOTAData.BufferIndex != FOTA_BUFFER_SIZE)
+            {
+               byte_ptr = (kal_uint8 *)(((kal_uint32)FOTAData.FOTAWriteBuffer) + FOTAData.BufferIndex);
+               //kal_mem_cpy((void*)&FOTAData.FOTABuffer[FOTAData.BufferIndex>>2], Buffer, FOTA_BUFFER_SIZE - FOTAData.BufferIndex);
+               kal_mem_cpy(byte_ptr, (void *)buff_addr, FOTA_BUFFER_SIZE - FOTAData.BufferIndex);
+               buff_addr += (FOTA_BUFFER_SIZE - FOTAData.BufferIndex);
+               Length -= (FOTA_BUFFER_SIZE - FOTAData.BufferIndex);
+               FOTAData.BufferIndex = FOTA_BUFFER_SIZE;
+            }
+            result = FOTA_MTD_Program_Buffer((void*)FOTAData.FOTAWriteBuffer, FOTA_BUFFER_SIZE);
+            if (result < 0)
+               return result;
+            FOTAData.BufferIndex = 0;
+         }
+      }
+      else
+      {
+         byte_ptr = (kal_uint8 *)(((kal_uint32)FOTAData.FOTAWriteBuffer) + FOTAData.BufferIndex);
+         //kal_mem_cpy((void*)&FOTAData.FOTABuffer[FOTAData.BufferIndex/4], Buffer, Length);
+         kal_mem_cpy(byte_ptr, (void *)buff_addr, Length);
+         FOTAData.BufferIndex += Length;
+         buff_addr += Length;
+         Length = 0;
+      }
+   }
+   return ERROR_FOTA_SUCCESS;   
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_ReadData
+DESCRIPTION
+   FOTA read data API
+   1. This function is used to read data from spare image pool
+   2. This API only support sequentially read operation, i.e. from low address to high address
+PARAMETER
+   Length: the length of reading (Unit: Bytes)
+   Buffer: the start address of buffer
+RETURN
+   0: means pass write success (ERROR_FOTA_SUCCESS)
+   < 0: writing action is fail
+      ERROR_FOTA_AUTH_ROMINFO: authentication fail, can't find rom info
+      ERROR_FOTA_AUTH_FATBEGIN: authentication fail, fat begin address is different
+      ERROR_FOTA_AUTH_FATLEN: authentication fail, fat length is different
+      ERROR_FOTA_AUTH_HCHECKSUM: authentication fail, header checksum fail
+      ERROR_FOTA_AUTH_ID: authentication fail, platform id is different
+      ERROR_FOTA_AUTH_VERSION: authentication fail, downgrade is not allowed
+      ERROR_FOTA_AUTH_IMAGELEN: authentication fail, image length too large
+	 ERROR_FOTA_AUTH_FAIL: authentication fail before
+	 ERROR_FOTA_OVERRANGE: write over the spare image pool range
+	 ERROR_FOTA_NOT_INITIALIZED: not call FOTA_Initialize before
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_ReadData(kal_uint32 Length, void* Buffer)
+{
+   kal_int32  result      = ERROR_FOTA_SUCCESS;
+   kal_uint32 buffer_addr = (kal_uint32)Buffer;
+   kal_uint32 read_len    = 0;
+   kal_uint32 copy_size   = 0;
+
+   if (FOTAData.Status == STATUS_FOTA_NOT_INITIAL)
+      return ERROR_FOTA_NOT_INITIALIZED;
+
+   while(Length > read_len)
+   {
+      if( ( (Length-read_len) >= FOTA_BUFFER_SIZE) && (0 == ((buffer_addr)&0x03)) )
+      {
+         /* directly read into user's buffer */
+         result = FOTA_MTD_Read_Buffer((void*)buffer_addr, FOTA_BUFFER_SIZE);
+         if(result < 0)
+            break;
+         buffer_addr += FOTA_BUFFER_SIZE;
+         read_len    += FOTA_BUFFER_SIZE;
+      }
+      else
+      {
+         if( (Length-read_len) >= FOTA_BUFFER_SIZE)
+            copy_size = FOTA_BUFFER_SIZE;
+         else
+            copy_size = (Length-read_len);
+
+         /* read into temporary buffer */
+         result = FOTA_MTD_Read_Buffer(FOTAData.FOTAReadBuffer, copy_size);
+         if (result < 0)
+            break;
+
+         kal_mem_cpy((void *)buffer_addr, FOTAData.FOTAReadBuffer, copy_size);
+         buffer_addr += copy_size;
+         read_len    += copy_size;
+      }
+   }
+
+   return result;   
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Finalize
+DESCRIPTION
+   FOTA finalization API
+   1. compare calculated checksum with image checksum in the header after 
+       whole image is written 
+   2. mark the status to UPDATE_NEEDED 
+PARAMETER
+   void
+RETURN
+   0: means pass error check step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_AUTH_FAIL: authentication fail, final step is not allowed
+      ERROR_FOTA_IMAGE_CHECKSUM: image checksum error
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_Finalize(void)
+{
+   kal_int32  result = 0;
+
+   if (FOTAData.Status == STATUS_FOTA_NOT_INITIAL)
+      return ERROR_FOTA_NOT_INITIALIZED;
+
+   if(FOTAData.BufferIndex != 0)
+   {
+      result = FOTA_MTD_Program_Buffer((void*)FOTAData.FOTAWriteBuffer, FOTAData.BufferIndex);
+      FOTA_FinishPackageBlock();
+      if (result < 0)
+         return result;
+      FOTAData.BufferIndex = 0;
+   }
+
+   FOTAData.Status = STATUS_FOTA_FINAL;
+
+   return ERROR_FOTA_SUCCESS;
+}
+
+/* --------------------------------------------------------------------------------- *
+ * Flash device wrapper functions
+ * --------------------------------------------------------------------------------- */
+
+/************************************************************************************
+ * NAND flash part
+ *************************************************************************************/
+static kal_int32 FOTA_MTD_Program_Buffer(void *Buffer, kal_uint32 write_len)
+{
+   kal_uint32 buff_offset = 0;
+   kal_int32 left_length = write_len;
+   kal_uint32 page_size = 0;
+   kal_int32  ret_code = ERROR_FOTA_SUCCESS;
+
+   if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
+   {
+      ASSERT(0);
+      return ERROR_FOTA_NOT_INITIALIZED;
+   }
+
+   while(left_length > 0)
+   {
+      ret_code = FOTA_ProgramPackagePage((void*)(((kal_uint32)Buffer)+buff_offset), &page_size);
+      if(ERROR_FOTA_SUCCESS == ret_code)
+      {
+         buff_offset += page_size;
+         left_length -= page_size;
+         FOTAData.SpareCurrWriteAddr += page_size;
+      }
+      else if( (ERROR_FOTA_NO_AVAILABLE_BLOCK == ret_code) || (ERROR_FOTA_FLASH_DEVICE==ret_code) ||
+              (ERROR_FOTA_UNSUPPORTED_CASES == ret_code) )
+      {
+         break;
+      }
+   }
+   return ret_code;
+
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_FinishePackageBlock
+DESCRIPTION
+   download is finished, complete current package block
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+        ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_FinishPackageBlock(void)
+{
+   kal_uint32               page_per_blk = 0;
+   FOTA_Package_Info_st     *pkg_info    = NULL;
+   kal_int32                ret_code     = ERROR_FOTA_SUCCESS;
+   FUE_ERROR_CODE           result       = ERROR_FUE_NONE;
+   Logical_Flash_info_st     info;
+   Flash_GAL_st              *fgal       = FOTA_Package_Ctrl.m_pkg_fgal;
+
+   if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
+   {
+      ASSERT(0);
+      return ERROR_FOTA_NOT_INITIALIZED;
+   }
+   ASSERT(fgal);
+   pkg_info = &FOTA_Package_Ctrl.m_fota_pkg_info;;
+   //page_per_blk = 1 << FOTA_Package_Ctrl.m_fota_flash_info.Flash_offset_shift;
+   fgal->query_info(&info);
+   page_per_blk = fgal->block_size(pkg_info->m_pkg_current_block)/info.Flash_page_size;
+
+   if(pkg_info->m_pkg_current_page == page_per_blk)
+   {
+      /* current package has been marked as complete in last package program operation */
+      if( pkg_info->m_pkg_valid_pages == (page_per_blk-3))
+      {
+         fue_dbg_print("FOTA_FinishPackageBlock: mark blk:%d as complete is already done!\n\r",\
+                        pkg_info->m_pkg_current_block);
+      }
+      #ifdef _FUE_PKG_DEBUG_
+      else
+      {
+         fue_dbg_print("FOTA_FinishPackageBlock: incomplete blk:%d has been marked complete already!\n\r",\
+                        pkg_info->m_pkg_current_block);
+         #if defined(__FOTA_DEBUG_ASSERT__)
+         ASSERT(0);
+         #endif /* __FOTA_DEBUG_ASSERT__ */
+      }
+      #endif /* _FUE_PKG_DEBUG_ */
+
+      /* indicate current package download is done */
+      FOTA_Package_Ctrl.m_fota_pkg_index = INVALID_DWORD;
+   }
+   else
+   {
+      while(1)
+      {
+         /* mark this package block as complete */
+         result = FUE_NFB_Mark_Package_Block_Complete(&FOTA_Package_Ctrl, pkg_info, fue_dbg_print);
+         if(ERROR_FUE_NONE == result)
+         {
+            fue_dbg_print("FOTA_FinishPackageBlock: mark blk:%d as complete done!\n\r",\
+                           pkg_info->m_pkg_current_block);
+            /* indicate current package download is done */
+            FOTA_Package_Ctrl.m_fota_pkg_index = INVALID_DWORD;
+            break;
+         }
+         else if(ERROR_FUE_PROGRAM_FAILED == result)
+         {
+            /* block replacement procedure - caused by marking complete function */
+            result = FUE_NFB_Replace_Current_Package_Block(&FOTA_Package_Ctrl, fota_replace_page_buffer, \
+                                                           fue_dbg_print);
+            if( ERROR_FUE_OVER_DESIGN == result )
+            {
+               ret_code = ERROR_FOTA_UNSUPPORTED_CASES;
+               break;
+            }
+            else if( ERROR_FUE_NO_AVAILABLE_BLOCK == result )
+            {
+               ret_code = ERROR_FOTA_NO_AVAILABLE_BLOCK;
+               break;
+            }
+            else if(ERROR_FUE_NOT_INITIALIZED == result)
+            {
+               ret_code = ERROR_FOTA_NOT_INITIALIZED;
+               break;
+            }
+         }
+         else
+         {
+            /* unexpected status, abort current update package */
+            fue_dbg_print("FOTA_FinishPackageBlock: unexpected error on blk:%d, Abort!!\n\r",\
+                           pkg_info->m_pkg_current_block);
+            break;
+         }
+      }
+   }
+   return ret_code;
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_ProgramPackagePage
+DESCRIPTION
+   clear downloaded update package
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+        ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_ProgramPackagePage(void* buff, kal_uint32 *page_size)
+{
+   kal_int32            ret_code     = ERROR_FOTA_SUCCESS;
+   kal_uint32           page_per_blk = 0;
+   kal_uint32           curr_blk     = INVALID_DWORD;
+   kal_uint32           curr_order   = INVALID_DWORD;
+   kal_uint32           alloc_block  = INVALID_DWORD;
+   FOTA_Package_Info_st *pkg_info    = NULL;
+   Logical_Flash_info_st     info;
+   Flash_GAL_st          *fgal       = FOTA_Package_Ctrl.m_pkg_fgal;
+   _FGAL_ERROR_CODE     status       = ERROR_FGAL_NONE;
+   FUE_ERROR_CODE       result       = ERROR_FUE_NONE;
+   kal_bool             op_done      = KAL_FALSE;
+   
+   if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
+   {
+      ASSERT(0);
+      return ERROR_FOTA_NOT_INITIALIZED;
+   }
+   ASSERT(fgal);
+
+   pkg_info     = &FOTA_Package_Ctrl.m_fota_pkg_info;
+   fgal         = FOTA_Package_Ctrl.m_pkg_fgal;
+   //page_per_blk = 1 << FOTA_Package_Ctrl.m_fota_flash_info.Flash_offset_shift;
+   fgal->query_info(&info);
+   *page_size   = 0;
+
+   if( INVALID_DWORD != pkg_info->m_pkg_current_block )
+   {
+      page_per_blk = fgal->block_size(pkg_info->m_pkg_current_block)/info.Flash_page_size;
+      if( pkg_info->m_pkg_current_page < (page_per_blk-1) )
+      {
+         do
+         {
+            if(pkg_info->m_pkg_current_page == (page_per_blk-2))
+            {
+               /* mark current package block as complete */
+               result = FUE_NFB_Mark_Package_Block_Complete(&FOTA_Package_Ctrl, pkg_info, fue_dbg_print);
+               if(ERROR_FUE_NONE == result)
+               {
+                  break;
+               }
+            }
+            else if(0 == *page_size)
+            {
+               status = fgal->write_page(buff, pkg_info->m_pkg_current_block, pkg_info->m_pkg_current_page);
+               if(ERROR_FGAL_NONE == status)
+               {
+                  pkg_info->m_pkg_current_page++;
+                  pkg_info->m_pkg_valid_pages++;
+                  FOTA_Package_Ctrl.m_fota_pkg_pages++;
+                  *page_size = info.Flash_page_size;
+                  op_done = KAL_TRUE;
+               }
+               else if(ERROR_FGAL_OPERATION_RETRY == status)
+               {
+                  ret_code = ERROR_FOTA_FLASH_DEVICE;
+                  break;
+               }
+            }
+            else
+            {
+               /* package page program done */
+               break;
+            }
+
+            if( (ERROR_FGAL_WRITE_FAILURE == status) || (ERROR_FUE_PROGRAM_FAILED == result) )
+            {
+               /* copy valid pages in bad block to new package block */
+               result = FUE_NFB_Replace_Current_Package_Block(&FOTA_Package_Ctrl, fota_replace_page_buffer, \
+                                                              fue_dbg_print);
+               if( ERROR_FUE_OVER_DESIGN == result )
+               {
+                  ret_code = ERROR_FOTA_UNSUPPORTED_CASES;
+                  break;
+               }
+               else if( ERROR_FUE_NO_AVAILABLE_BLOCK == result )
+               {
+                  ret_code = ERROR_FOTA_NO_AVAILABLE_BLOCK;
+                  break;
+               }
+               else if( ERROR_FUE_NOT_INITIALIZED == result )
+               {
+                  ret_code = ERROR_FOTA_NOT_INITIALIZED;
+                  break;
+               }
+            }
+         }while(1);
+      }
+   }
+   /* 
+    * else start to allocate new package block 
+    */
+
+   if(!op_done)
+   {
+      if(INVALID_DWORD == pkg_info->m_pkg_current_block)
+      {
+         ASSERT(INVALID_DWORD == FOTA_Package_Ctrl.m_fota_pkg_index);
+         ASSERT(INVALID_DWORD == pkg_info->m_pkg_block_session);
+         curr_blk = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_base;
+         curr_order = INVALID_DWORD;
+      }
+      else
+      {
+         ASSERT(INVALID_DWORD != FOTA_Package_Ctrl.m_fota_pkg_index);
+         curr_blk = pkg_info->m_pkg_current_block;
+         curr_order = FOTA_Package_Ctrl.m_fota_pkg_list[FOTA_Package_Ctrl.m_fota_pkg_index].m_pkg_block_order;
+         FOTA_Package_Ctrl.m_fota_pkg_list[FOTA_Package_Ctrl.m_fota_pkg_index].m_pkg_valid_pages = 
+                                           pkg_info->m_pkg_valid_pages;
+         FOTA_Package_Ctrl.m_fota_pkg_list[FOTA_Package_Ctrl.m_fota_pkg_index].m_pkg_block_complete = 
+                                           KAL_TRUE;
+      }
+      while(1)
+      {
+         /* allocate new package block */
+         result = FUE_NFB_Allocate_PackageBlock(&FOTA_Package_Ctrl, curr_blk, &alloc_block, fue_dbg_print);
+         if(ERROR_FUE_NONE == result)
+         {
+            status = fgal->erase_block(alloc_block);
+            if(ERROR_FGAL_ERASE_FAILURE == status)
+            {
+               fgal->mark_bad(alloc_block);
+               curr_blk = alloc_block;
+               continue;
+            }
+            else if(ERROR_FGAL_NONE != status)
+            {
+               fue_dbg_print("FOTA_ProgramPackagePage: erase operation on block:%d error!\n\r", \
+                              alloc_block);
+               ret_code = ERROR_FOTA_FLASH_DEVICE;
+               break;
+            }
+            /* create package block */
+            result = FUE_NFB_Create_Package_Block(&FOTA_Package_Ctrl, alloc_block, \
+                                                  pkg_info->m_pkg_current_block,\
+                                                  INVALID_DWORD, KAL_TRUE, fue_dbg_print);
+            if( (ERROR_FUE_INSUFFICIENT_BUFFER == result) || (ERROR_FUE_INVALID_PARAMETER == result) )
+            {
+               ret_code = ERROR_FOTA_INVALID_PARAMETER;
+               break;
+            }
+            else if(ERROR_FUE_NONE == result)
+            {
+               status = fgal->write_page(buff, alloc_block, 1);
+               if(ERROR_FGAL_NONE == status)
+               {
+                  /* program done, update RAM copy information */
+                  FOTA_Package_Ctrl.m_fota_pkg_index++;
+                  FOTA_Package_Ctrl.m_fota_pkg_pages++;
+                  FOTA_Package_Ctrl.m_fota_pkg_list[FOTA_Package_Ctrl.m_fota_pkg_index].m_pkg_block_position = 
+                  alloc_block;
+                  FOTA_Package_Ctrl.m_fota_pkg_list[FOTA_Package_Ctrl.m_fota_pkg_index].m_pkg_block_order = 
+                  curr_order+1;
+
+                  pkg_info->m_pkg_previous_block = pkg_info->m_pkg_current_block;
+                  pkg_info->m_pkg_current_block = alloc_block;
+                  pkg_info->m_pkg_current_page = 2;
+                  pkg_info->m_pkg_valid_pages = 1;
+                  pkg_info->m_pkg_block_session++;
+                  *page_size = info.Flash_page_size;
+
+                  fue_dbg_print("FOTA_ProgramPackagePage: program on new package block:%d done!\n\r", \
+                                 pkg_info->m_pkg_current_block);
+                  break;
+               }
+            }
+            //else if(ERROR_FUE_PROGRAM_FAILED == result)
+            if( (ERROR_FUE_PROGRAM_FAILED == result) || (ERROR_FGAL_WRITE_FAILURE == status) )
+            {
+               /* create package block or program new page failed - try again */
+               fgal->erase_block(alloc_block);
+               fgal->mark_bad(alloc_block);
+               curr_blk = alloc_block;
+               continue;
+            }
+            else if(ERROR_FUE_OPERATION_STOP == result)
+            {
+               ret_code = ERROR_FOTA_FLASH_DEVICE;
+               break;
+            }
+            else if(ERROR_FUE_OVER_DESIGN == result)
+            {
+               ret_code = ERROR_FOTA_UNSUPPORTED_CASES;
+               break;
+            }
+         }
+         else if(ERROR_FUE_NO_AVAILABLE_BLOCK == result)
+         {
+            ret_code = ERROR_FOTA_NO_AVAILABLE_BLOCK;
+            break;
+         }
+      }
+   }
+   return ret_code;
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_ReadPackagePage
+DESCRIPTION
+   clear downloaded update package
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+        ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_ReadPackagePage(void* buff, kal_uint32 page_addr, kal_uint32 *page_size)
+{
+   kal_int32            ret_code     = ERROR_FOTA_SUCCESS;
+   kal_uint32           page_count   = 0;
+   kal_int32            left_pages   = 0;
+   kal_uint32           blk_idx      = 0;
+   kal_uint32           page_idx     = 0;
+   kal_uint32           phy_blk      = 0;
+   FOTA_Package_Info_st *pkg_info    = NULL;
+   Logical_Flash_info_st info;
+   FOTA_Package_Access_st *pkg_read  = &FOTA_Package_Ctrl.m_fota_curr_read;
+   Flash_GAL_st          *fgal       = FOTA_Package_Ctrl.m_pkg_fgal;
+   _FGAL_ERROR_CODE     status       = ERROR_FGAL_NONE;
+   
+   if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
+   {
+      ASSERT(0);
+      return ERROR_FOTA_NOT_INITIALIZED;
+   }
+   ASSERT(fgal);
+   *page_size = 0;
+
+   fgal     = FOTA_Package_Ctrl.m_pkg_fgal;
+   pkg_info = &FOTA_Package_Ctrl.m_fota_pkg_info;
+   fgal->query_info(&info);
+   if( ((pkg_read->m_pkg_curr_addr+info.Flash_page_size) != page_addr) || (INVALID_DWORD == pkg_read->m_pkg_curr_addr))
+   {
+      page_idx = page_addr/info.Flash_page_size;
+      for(blk_idx = 0 ; blk_idx <= FOTA_Package_Ctrl.m_fota_pkg_index ; blk_idx++)
+      {
+         phy_blk = FOTA_Package_Ctrl.m_fota_pkg_list[blk_idx].m_pkg_block_position;
+         page_count = (fgal->block_size(phy_blk)/info.Flash_page_size) - 3;
+         if(page_idx < page_count)
+            break;
+         else
+            page_idx -= page_count;
+      }
+   }
+   else
+   {
+      blk_idx = pkg_read->m_pkg_curr_blk;
+      phy_blk = FOTA_Package_Ctrl.m_fota_pkg_list[blk_idx].m_pkg_block_position;
+      page_count = (fgal->block_size(phy_blk)/info.Flash_page_size) - 3;
+      if( (pkg_read->m_pkg_curr_page+1) == page_count)
+      {
+         /* advance to next block */
+         blk_idx = pkg_read->m_pkg_curr_blk+1;
+         page_idx = 0;
+      }
+      else
+      {
+         blk_idx = pkg_read->m_pkg_curr_blk;
+         page_idx = pkg_read->m_pkg_curr_page+1;
+      }
+   }
+
+   /* sanity check 
+    * !CAUTION! all package blocks are assumed to have same size.
+    */
+   left_pages = FOTA_Package_Ctrl.m_fota_pkg_pages - blk_idx*page_count;
+   if( (blk_idx > FOTA_Package_Ctrl.m_fota_pkg_index) ||
+       ((blk_idx == FOTA_Package_Ctrl.m_fota_pkg_index) && ((page_idx+1) > left_pages)) )
+   {
+      fue_dbg_print("FOTA_ReadPackagePage: read over range:(%d,%d) > (%d,%d)!\n\r", \
+                     blk_idx, page_idx, FOTA_Package_Ctrl.m_fota_pkg_index, pkg_info->m_pkg_valid_pages);
+      ret_code = ERROR_FOTA_OVERRANGE;
+      return ret_code;
+   }
+   else
+   {
+      pkg_read->m_pkg_curr_addr = page_addr;
+      pkg_read->m_pkg_curr_blk = blk_idx;
+      pkg_read->m_pkg_curr_page = page_idx;
+      phy_blk = FOTA_Package_Ctrl.m_fota_pkg_list[blk_idx].m_pkg_block_position;
+      status = fgal->read_page((kal_uint32 *)buff, phy_blk, page_idx+1);/* plus one to bypass header page */
+      if(ERROR_FGAL_NONE == status)
+      {
+         //*page_size = FOTA_Package_Ctrl.m_fota_flash_info.Flash_page_size;
+         *page_size = info.Flash_page_size;
+      }
+      else if(ERROR_FGAL_READ_FAILURE == status)
+      {
+         ret_code = ERROR_FOTA_READ;
+      }
+      else if(ERROR_FGAL_OPERATION_RETRY == status)
+      {
+         ret_code = ERROR_FOTA_UNSUPPORTED_CASES;
+      }
+      else if(ERROR_FGAL_INVALID_PARAMETER == status)
+      {
+         ret_code = ERROR_FOTA_INVALID_PARAMETER;
+      }
+   }
+
+   return ret_code;
+}
+
+/* --------------------------------------------------------------------------------- */
+static kal_int32 FOTA_MTD_Read_Buffer(void *Buffer, kal_uint32 read_len)
+{
+   kal_uint32 buff_offset       = 0;
+   kal_int32 left_length        = read_len;
+   kal_int32  result            = 0;
+   kal_uint32 page_size         = 0;
+   kal_uint32 buff_addr         = (kal_uint32)Buffer;
+
+   while(left_length > 0)
+   {
+      result = FOTA_ReadPackagePage((void*)(buff_addr+buff_offset), FOTAData.SpareCurrReadAddr, \
+                                    &page_size);
+
+      if(ERROR_FOTA_SUCCESS == result)
+      {
+         buff_offset += page_size;
+         left_length -= page_size;
+         FOTAData.SpareCurrReadAddr += page_size;
+      }
+      else
+         break;
+   }
+   return result;
+}
+
+/* --------------------------------------------------------------------------------- *
+ * Update package download module
+ * --------------------------------------------------------------------------------- */
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_InitializePackageReservoir
+DESCRIPTION
+   find out whether any update record block exists
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_InitializePackageReservoir(void)
+{
+   kal_uint32               idx         = 0;
+   kal_int32                ret_code    = ERROR_FOTA_SUCCESS;
+
+   /* set package module control to default value */
+   FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_block_session  = INVALID_DWORD;
+   FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_previous_block = INVALID_DWORD;
+   FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_block  = INVALID_DWORD;
+   FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_valid_pages    = INVALID_DWORD;
+   FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_page   = INVALID_DWORD;
+
+   FOTA_Package_Ctrl.m_fota_pkg_index                     = INVALID_DWORD;
+   FOTA_Package_Ctrl.m_fota_pkg_pages                     = 0;
+
+   FOTA_Package_Ctrl.m_fota_curr_read.m_pkg_curr_addr = INVALID_DWORD;
+   FOTA_Package_Ctrl.m_fota_curr_read.m_pkg_curr_blk = INVALID_DWORD;
+   FOTA_Package_Ctrl.m_fota_curr_read.m_pkg_curr_page = INVALID_DWORD;
+
+   for(idx = 0 ; idx < FOTA_PKG_BLOCKS ; idx++)
+   {
+      FOTA_Package_Ctrl.m_fota_pkg_list[idx].m_pkg_block_order = INVALID_DWORD;
+      FOTA_Package_Ctrl.m_fota_pkg_list[idx].m_pkg_block_position = INVALID_DWORD;
+      FOTA_Package_Ctrl.m_fota_pkg_list[idx].m_pkg_valid_pages = INVALID_DWORD;
+      FOTA_Package_Ctrl.m_fota_pkg_list[idx].m_pkg_block_complete = KAL_FALSE;
+   }
+
+   /* initialize FGAL driver */
+   FOTA_Package_Ctrl.m_pkg_fgal = FOTA_Setup_FGAL();
+
+   /* get initial reserved area information */
+   FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_base = FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start;
+   FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_end = FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end;
+
+   /* get flash information */
+   //FOTA_Package_Ctrl.m_pkg_fgal->query_info(&FOTA_Package_Ctrl.m_fota_flash_info);
+
+   FOTA_Package_Ctrl.m_fota_pkg_state = FOTA_UPDATE_PACKAGE_STATE;
+
+   return ret_code;
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_ResumeUpdatePackage
+DESCRIPTION
+   find out whether any valid update package blocks exist
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_ResumeUpdatePackage(void)
+{
+   kal_uint32               pkg_blocks  = INVALID_DWORD;
+   kal_uint32               buff_len    = FOTA_FLASH_MAX_PAGE_SIZE;
+   kal_uint32               idx         = 0;
+   kal_uint32               start_idx   = INVALID_DWORD;
+   kal_uint32               blk_order   = 0;
+   FUE_ERROR_CODE           result      = ERROR_FUE_NONE;
+   kal_int32                ret_code    = ERROR_FOTA_SUCCESS;
+   kal_uint32               pkg_pages   = 0;
+   FOTA_Package_List_st     *pkg_list   = NULL;
+   Logical_Flash_info_st    info;
+   Flash_GAL_st             *fgal       = FOTA_Package_Ctrl.m_pkg_fgal;
+
+   if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
+   {
+      ret_code = ERROR_FOTA_NOT_INITIALIZED;
+      return ret_code;
+   }
+
+   /* try to resume interrupted download process */
+   /* update current package state to RAM copy   */
+   result = FUE_BlkInfo_Resume_Package_Blocks(&FOTA_Package_Ctrl, &pkg_blocks, g_fota_package_blocks,
+                                              fota_temp_page_buffer, &buff_len,
+                                              fue_dbg_print);
+   if(ERROR_FUE_NONE == result)
+   {
+      if( pkg_blocks )
+      {
+         /* get first element index */
+         for(idx = 0 ; idx < FOTA_PKG_BLOCKS ; idx++)
+         {
+            if( INVALID_DWORD == g_fota_package_blocks[idx].m_pkg_prev_idx )
+            {
+               if( INVALID_DWORD != g_fota_package_blocks[idx].m_pkg_block_order )
+               {
+                  start_idx = idx;
+                  break;
+               }
+            }
+         }
+         #ifdef _FUE_PKG_DEBUG_
+         if( INVALID_DWORD == start_idx )
+         {
+            fue_dbg_print("FOTA_ResumeUpdatePackage: first valid block not found in %d blocks!\n\r", pkg_blocks);
+            #if defined(__FOTA_DEBUG_ASSERT__)
+            ASSERT(0);
+            #endif /* __FOTA_DEBUG_ASSERT__ */
+         }
+         #endif
+
+         pkg_list = FOTA_Package_Ctrl.m_fota_pkg_list;
+         while(blk_order < pkg_blocks)
+         {
+            idx = start_idx;
+            while(1)
+            {
+               if(blk_order == g_fota_package_blocks[idx].m_pkg_block_order)
+               {
+                  pkg_list[blk_order].m_pkg_block_order = g_fota_package_blocks[idx].m_pkg_block_order;
+                  pkg_list[blk_order].m_pkg_block_position = g_fota_package_blocks[idx].m_pkg_block_position;
+                  pkg_list[blk_order].m_pkg_valid_pages = g_fota_package_blocks[idx].m_pkg_valid_pages;
+                  pkg_list[blk_order].m_pkg_block_complete = g_fota_package_blocks[idx].m_pkg_block_complete;
+                  pkg_pages += pkg_list[blk_order].m_pkg_valid_pages;
+                  if( (INVALID_DWORD == pkg_list[blk_order].m_pkg_valid_pages) ||
+                      (0 == pkg_list[blk_order].m_pkg_valid_pages) )
+                  {
+                     #ifdef _FUE_PKG_DEBUG_
+                     fue_dbg_print("FOTA_ResumeUpdatePackage: resume operation failed on %dth blk:%d\n\r", \
+                                   blk_order, pkg_list[blk_order].m_pkg_block_position);
+                     #endif /* _FUE_PKG_DEBUG_ */
+                     #if defined(__FOTA_DEBUG_ASSERT__)
+                     ASSERT(0);
+                     #endif /* __FOTA_DEBUG_ASSERT__ */
+                  }
+                  blk_order++;
+                  break;
+                  /*TODO: remove this element from g_fota_package_blocks to save searching time */
+               }
+               idx = g_fota_package_blocks[idx].m_pkg_next_idx;
+               if(INVALID_DWORD == idx)
+               {
+                  #ifdef _FUE_PKG_DEBUG_
+                  fue_dbg_print("FOTA_ResumeUpdatePackage: downloading sequence is lost!(%d,%d)\n\r", \
+                                blk_order, pkg_blocks);
+                  #if defined(__FOTA_DEBUG_ASSERT__)
+                  ASSERT(0);
+                  #endif /* __FOTA_DEBUG_ASSERT__ */
+                  #endif /* _FUE_PKG_DEBUG_ */
+                  /* package block order is lost, re-download package from the beggining  */
+                  ret_code = ERROR_FOTA_NO_UPDATE_PACKAGE;
+                  break;
+               }
+            }
+         }
+
+         #ifdef _FUE_PKG_DEBUG_
+         #if 0 /* removed since we do not update m_fota_pkg_info during FUE_BlkInfo_Resume_Package_Blocks() */
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+         #endif /* removed */
+         #endif
+         if(INVALID_DWORD != FOTA_Package_Ctrl.m_fota_pkg_list[blk_order-1].m_pkg_block_position)
+         {
+            FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_block = 
+               FOTA_Package_Ctrl.m_fota_pkg_list[blk_order-1].m_pkg_block_position;
+            if(pkg_list[blk_order-1].m_pkg_block_complete)
+            {
+               fgal->query_info(&info);
+               FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_page = 
+               fgal->block_size(FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_block)/info.Flash_page_size;
+            }
+            else
+            {
+            FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_page = pkg_list[blk_order-1].m_pkg_valid_pages+1;
+            }
+
+            FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_valid_pages = pkg_list[blk_order-1].m_pkg_valid_pages;
+            FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_block_session = blk_order-1;
+            FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_previous_block = (blk_order > 1) ? 
+               FOTA_Package_Ctrl.m_fota_pkg_list[blk_order-2].m_pkg_block_position : INVALID_DWORD;
+         }
+         FOTA_Package_Ctrl.m_fota_pkg_index = blk_order-1;
+         FOTA_Package_Ctrl.m_fota_pkg_blocks = pkg_blocks;
+         FOTA_Package_Ctrl.m_fota_pkg_pages = pkg_pages;
+
+         //FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_valid_pages = ;
+         if(pkg_blocks != blk_order)
+         {
+            #ifdef _FUE_PKG_DEBUG_
+            fue_dbg_print("FOTA_ResumeUpdatePackage: blk number:%d <-> blk order:%d!\n\r", \
+                          pkg_blocks, blk_order);
+            #endif /* _FUE_PKG_DEBUG_ */
+            #if defined(__FOTA_DEBUG_ASSERT__)
+            ASSERT(0);
+            #endif /* __FOTA_DEBUG_ASSERT__ */
+            ret_code = ERROR_FOTA_NO_UPDATE_PACKAGE;
+         }
+         #ifdef _FUE_PKG_DEBUG_
+         fue_dbg_print("FOTA_ResumeUpdatePackage: %dth package blk:%d!\n\r",
+                        FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_block_session, \
+                        FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_block);
+         #endif
+      }
+      else
+      {
+         ret_code = ERROR_FOTA_NO_UPDATE_PACKAGE;
+      }
+   }
+   else if((ERROR_FUE_INSUFFICIENT_BUFFER == result) || (ERROR_FUE_INVALID_PARAMETER == result))
+   {
+      ret_code = ERROR_FOTA_INVALID_PARAMETER;
+      FOTA_Package_Ctrl.m_fota_pkg_state = INVALID_DWORD;
+   }
+   else if( (ERROR_FUE_NOT_FOUND == result) || (ERROR_FUE_TOO_MANY_PACKAGE_BLOCKS == result) )
+   {
+      ret_code = ERROR_FOTA_NO_UPDATE_PACKAGE;
+   }
+   else if( (ERROR_FUE_OPERATION_STOP == result) || (ERROR_FUE_READ_FAILURE == result) )
+   {
+      ret_code = ERROR_FOTA_UNSUPPORTED_CASES;
+   }
+
+   return ret_code;
+}
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_CheckAvailablePackageBlocks
+DESCRIPTION
+   scan all block in package reservoir area to estimate the available storage size
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_CheckAvailablePackageBlocks(kal_uint32 *available_num)
+{
+   kal_int32  ret_code       = ERROR_FOTA_SUCCESS;
+   kal_uint32 base_blk       = INVALID_DWORD;
+   kal_uint32 end_blk        = INVALID_DWORD;
+   kal_uint32 blk_idx        = 0;
+   kal_uint32 blk_num        = 0;
+   _FGAL_ERROR_CODE   status = ERROR_FGAL_NONE;
+   Flash_GAL_st  *fgal  = NULL;
+   //Logical_Flash_info_st  info;
+
+   if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
+   {
+      ASSERT(0);
+      return ERROR_FOTA_NOT_INITIALIZED;
+   }
+
+   base_blk = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_base;
+   end_blk  = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_end;
+
+   fgal = FOTA_Package_Ctrl.m_pkg_fgal;
+
+   //fgal->query_info(&info);
+   *available_num = 0;
+
+   for(blk_idx = base_blk ; blk_idx < (end_blk+1) ; blk_idx++)
+   {
+      status = fgal->check_block(blk_idx);
+      if(ERROR_FGAL_NONE == status)
+      {
+         /* check whether it is occupied */
+         if(FUE_NFB_Is_Available_Block(blk_idx, fota_temp_page_buffer, fgal, fue_dbg_print))
+         {
+            blk_num++;
+         }
+      }
+      else if(ERROR_FGAL_READ_FAILURE == status)
+      {
+         ret_code = ERROR_FOTA_READ;
+         break;
+      }
+      else if(ERROR_FGAL_OPERATION_RETRY == status)
+      {
+         ret_code = ERROR_FOTA_FLASH_DEVICE;
+         break;
+      }
+   }
+   if(blk_idx == (end_blk+1))
+      *available_num = blk_num;
+
+   return ret_code;
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_ClearPackageReservoir
+DESCRIPTION
+   clear downloaded update package
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+        ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_ClearPackageReservoir(void)
+{
+   kal_int32  ret_code         = ERROR_FOTA_SUCCESS;
+   kal_uint32 base_blk         = INVALID_DWORD;
+   kal_uint32 end_blk          = INVALID_DWORD;
+   kal_uint32 index            = 0;
+   kal_uint32 blk_idx          = 0;
+   kal_uint32 erase_round      = 0;
+   kal_uint32 pkg_num          = FOTA_PKG_BLOCKS;
+   kal_uint32 erased_blk       = 0;
+   FUE_ERROR_CODE  result      = ERROR_FUE_NOT_FOUND;
+   _FGAL_ERROR_CODE       status   = ERROR_FGAL_NONE;
+   Flash_GAL_st           *fgal    = NULL;
+
+   if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
+   {
+      return ERROR_FOTA_NOT_INITIALIZED;
+   }
+
+   base_blk = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_base;
+   end_blk  = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_end;
+
+   fgal = FOTA_Package_Ctrl.m_pkg_fgal;
+
+   /* try to erase all blocks occupied by update package */
+   for( blk_idx = base_blk ; blk_idx <= end_blk ; blk_idx++ )
+   {
+       status = fgal->check_block(blk_idx);
+       if(ERROR_FGAL_NONE == status)
+       {
+           result = FUE_BlkInfo_Is_Update_Block(&FOTA_Update_Ctrl, blk_idx, fue_dbg_print);
+           if(ERROR_FUE_NOT_FOUND == result) /* in this flash space, only package or update blocks exist */
+           {
+               /* erase block */
+               status = fgal->erase_block(blk_idx);
+               if(ERROR_FGAL_ERASE_FAILURE == status)
+               {
+                   fgal->mark_bad(blk_idx);
+                   #ifdef _FUE_PKG_DEBUG_
+                   fue_dbg_print("FOTA_ClearPackageReservoir: erase failed on block:%d!\n\r", blk_idx);
+                   #endif
+               }
+               else if(ERROR_FGAL_OPERATION_RETRY == status)
+               {
+                   #ifdef _FUE_PKG_DEBUG_
+                   fue_dbg_print("FOTA_ClearPackageReservoir: erase operation stopped on block:%d!\n\r", blk_idx);
+                   #endif
+                   ret_code = ERROR_FOTA_FLASH_DEVICE;
+                   break;
+               }
+               erased_blk++;
+           }
+           else if( (ERROR_FUE_OPERATION_STOP == result) || (ERROR_FUE_OVER_DESIGN == result) )
+           {
+               #ifdef _FUE_PKG_DEBUG_
+               fue_dbg_print("FOTA_ClearPackageReservoir: read operation stopped on block:%d!\n\r", blk_idx);
+               #endif
+               ret_code = ERROR_FOTA_FLASH_DEVICE;
+               break;
+           }
+           else if(ERROR_FUE_NONE == result)
+           {
+               continue;
+           }
+           else
+           {
+               #ifdef _FUE_PKG_DEBUG_
+               fue_dbg_print("FOTA_ClearPackageReservoir: unexpected error on block:%d!\n\r", blk_idx);
+               #endif
+               ret_code = ERROR_FOTA_UNSUPPORTED_CASES;
+               break;
+           }
+       }
+       else if(ERROR_FGAL_READ_FAILURE == status)
+       {
+           ret_code = ERROR_FOTA_READ;
+           break;
+       }
+       else if(ERROR_FGAL_OPERATION_RETRY == status)
+       {
+           ret_code = ERROR_FOTA_FLASH_DEVICE;
+           break;
+       }
+   }
+   #ifdef _FUE_PKG_DEBUG_
+   fue_dbg_print("FOTA_ClearPackageReservoir: clear %d in %d blocks!\n\r", erased_blk, blk_idx-base_blk);
+   #endif
+   return ret_code;
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Get_TotalPackageBlock
+DESCRIPTION
+   return current package block number
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_Get_TotalPackageBlock(kal_uint32 *pkg_blks, kal_uint32* pkg_pages)
+{
+   if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
+   {
+      ASSERT(0);
+      return ERROR_FOTA_NOT_INITIALIZED;
+   }
+
+   if(INVALID_DWORD != FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_valid_pages)
+   {
+      *pkg_blks = FOTA_Package_Ctrl.m_fota_pkg_blocks-1;
+      *pkg_pages = FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_valid_pages;
+   }
+   else
+   {
+      *pkg_blks = FOTA_Package_Ctrl.m_fota_pkg_blocks;
+      *pkg_pages = 0;
+   }
+   
+   return ERROR_FOTA_SUCCESS;
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Get_CurrentPackagePosition
+DESCRIPTION
+   return current package block position
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_Get_CurrentPackagePosition(kal_uint32 *curr_blk, kal_uint32* curr_page)
+{
+   if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
+   {
+      ASSERT(0);
+      return ERROR_FOTA_NOT_INITIALIZED;
+   }
+
+   *curr_blk = FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_block;
+   *curr_page = FOTA_Package_Ctrl.m_fota_pkg_info.m_pkg_current_page;
+   
+   return ERROR_FOTA_SUCCESS;
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Get_AvailablePackageSpace
+DESCRIPTION
+   return currently downloaded package size
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_Get_AvailablePackageSpace(kal_uint32 *avail_size)
+{
+   Logical_Flash_info_st   info;
+   kal_int32               ret_code  = ERROR_FOTA_SUCCESS;
+   kal_uint32              page_size;
+   kal_uint32              blk_idx   = 0;
+   kal_uint32              start_blk = 0;
+   kal_uint32              end_blk   = 0;
+   kal_uint32              free_size = 0;
+   _FGAL_ERROR_CODE        status    = ERROR_FGAL_NONE;
+   Flash_GAL_st            *fgal     = NULL;
+
+   if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
+   {
+      ASSERT(0);
+      return ERROR_FOTA_NOT_INITIALIZED;
+   }
+
+   fgal = FOTA_Package_Ctrl.m_pkg_fgal;
+
+   fgal->query_info(&info);
+   page_size = info.Flash_page_size;
+   start_blk = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_base;
+   end_blk  = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_end;
+
+   /* try to erase all blocks occupied by update package */
+   for( blk_idx = start_blk ; blk_idx <= end_blk ; blk_idx++ )
+   {
+      status = fgal->check_block(blk_idx);
+      if(ERROR_FGAL_NONE == status)
+      {
+         /* check whether it is occupied */
+         if( FUE_NFB_Is_Available_Block(blk_idx, fota_temp_page_buffer, fgal, fue_dbg_print) ||
+         	   FUE_BlkInfo_Is_Package_Block(&FOTA_Package_Ctrl, blk_idx, fue_dbg_print) )
+         {
+            free_size += fgal->block_size(blk_idx)-3*page_size;/* header and end mark pages are reserved */
+         }
+      }
+      else if(ERROR_FGAL_READ_FAILURE == status)
+      {
+         ret_code = ERROR_FOTA_READ;
+         break;
+      }
+      else if(ERROR_FGAL_OPERATION_RETRY == status)
+      {
+         ret_code = ERROR_FOTA_FLASH_DEVICE;
+         break;
+      }
+   }
+
+   FOTA_Get_CurrentPackagePosition(&start_blk, &end_blk);
+   if(INVALID_DWORD != start_blk)
+   {
+      /* header, end mark and current valid pages are excluded */
+      free_size += fgal->block_size(start_blk)-(end_blk+3)*page_size; 
+   }
+
+   *avail_size = free_size;
+
+   return ret_code;
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Get_TotalPackageSpace
+DESCRIPTION
+   return currently downloaded package size
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_Get_TotalPackageSpace(kal_uint32 *avail_size)
+{
+   Logical_Flash_info_st   info;
+   kal_int32               ret_code  = ERROR_FOTA_SUCCESS;
+   kal_uint32              page_size;
+   kal_uint32              blk_idx   = 0;
+   kal_uint32              start_blk = 0;
+   kal_uint32              end_blk   = 0;
+   kal_uint32              free_size = 0;
+   _FGAL_ERROR_CODE        status    = ERROR_FGAL_NONE;
+   Flash_GAL_st            *fgal     = NULL;
+
+   if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
+   {
+      ASSERT(0);
+      return ERROR_FOTA_NOT_INITIALIZED;
+   }
+
+   fgal = FOTA_Package_Ctrl.m_pkg_fgal;
+
+   fgal->query_info(&info);
+   page_size = info.Flash_page_size;
+   start_blk = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_base;
+   end_blk  = FOTA_Package_Ctrl.m_fota_pkg_area.FOTA_pkg_area_end;
+
+   /* try to erase all blocks occupied by update package */
+   for( blk_idx = start_blk ; blk_idx <= end_blk ; blk_idx++ )
+   {
+      status = fgal->check_block(blk_idx);
+      if(ERROR_FGAL_NONE == status)
+      {
+         /* check whether it is occupied */
+         if( (ERROR_FUE_NONE == FUE_NFB_Is_Available_Block(blk_idx, fota_temp_page_buffer, fgal, fue_dbg_print)) ||
+             (ERROR_FUE_NONE == FUE_BlkInfo_Is_Package_Block(&FOTA_Package_Ctrl, blk_idx, fue_dbg_print)) )
+         {
+            free_size += fgal->block_size(blk_idx)-3*page_size;/* header and end mark pages are reserved */
+         }
+      }
+      else if(ERROR_FGAL_READ_FAILURE == status)
+      {
+         ret_code = ERROR_FOTA_READ;
+         break;
+      }
+      else if(ERROR_FGAL_OPERATION_RETRY == status)
+      {
+         ret_code = ERROR_FOTA_FLASH_DEVICE;
+         break;
+      }
+   }
+
+   /* one block is reserved for update state record replacement */
+   *avail_size = free_size-(fgal->block_size(start_blk)-3*page_size);/* header and end mark pages are reserved */
+
+   return ret_code;
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Get_DownloadedPackageSize
+DESCRIPTION
+   return currently downloaded package size
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_Get_DownloadedPackageSize(kal_uint32 *curr_size)
+{
+   Logical_Flash_info_st   info;
+   if(FOTA_UPDATE_PACKAGE_STATE != FOTA_Package_Ctrl.m_fota_pkg_state)
+   {
+      ASSERT(0);
+      return ERROR_FOTA_NOT_INITIALIZED;
+   }
+
+   FOTA_Package_Ctrl.m_pkg_fgal->query_info(&info);
+   if(INVALID_DWORD != FOTA_Package_Ctrl.m_fota_pkg_pages)
+      *curr_size = FOTA_Package_Ctrl.m_fota_pkg_pages*info.Flash_page_size;
+   else
+       *curr_size = 0;
+  
+   return ERROR_FOTA_SUCCESS;
+}
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+/* --------------------------------------------------------------------------------- *
+ * Update staus record control module
+ * --------------------------------------------------------------------------------- */
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_InitializeUpdateRecord
+DESCRIPTION
+   create an update record block or find out the existing update record block 
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_InitializeUpdateRecord(void)
+{
+   kal_uint32              start_block = INVALID_DWORD;
+   kal_uint32              end_block   = INVALID_DWORD;
+   FUE_ERROR_CODE          result      = ERROR_FUE_NONE;
+   _FGAL_ERROR_CODE        status      = ERROR_FGAL_NONE;
+
+   /* initialize FGAL driver */
+   FOTA_Update_Ctrl.m_update_fgal = FOTA_Setup_FGAL();
+
+   /* get initial reserved area information */
+   start_block = FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start;
+   end_block = FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end;
+   //FOTA_Update_Ctrl.m_update_fgal->query_info(&FOTA_Update_Ctrl.m_nand_flash_info);
+
+   /* set up update record module */
+   result = FUE_InitializeUpdateRecord(start_block, end_block, \
+                                       FOTA_Update_Ctrl.m_update_fgal/*&FOTA_Nand_Fgal*/,\
+                                       fue_dbg_print);
+   if(ERROR_FUE_NO_AVAILABLE_BLOCK == result)
+   {
+      status = ERROR_FOTA_NO_AVAILABLE_BLOCK;
+   }
+   else if(ERROR_FUE_OPERATION_STOP == result)
+   {
+      status = ERROR_FOTA_FLASH_DEVICE;
+   }
+   else if(ERROR_FUE_OVER_DESIGN == result)
+   {
+      status = ERROR_FOTA_UNSUPPORTED_CASES;
+   }
+   else
+   {
+      FOTA_Update_Ctrl.FOTA_UPDATE_ID = UPDATE_STATE_RECORD_ID;
+   }
+
+   return status;
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_WriteUpdateRecord
+DESCRIPTION
+   FOTA update state information write API
+   download client and update agent use this information to communicate with each other
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_WriteUpdateRecord(FOTA_Custom_Update_Info* record)
+{
+   kal_int32 ret            = ERROR_FOTA_SUCCESS;
+   FUE_ERROR_CODE  result   = ERROR_FUE_NONE;
+
+   /* check whether FOTA is initialized */
+   if(UPDATE_STATE_RECORD_ID != FOTA_Update_Ctrl.FOTA_UPDATE_ID)
+   {
+      ret = ERROR_FOTA_NOT_INITIALIZED;
+   }
+   else
+   {
+      result = FUE_NFB_Flush_Update_Record(record, fue_dbg_print);
+
+      if(ERROR_FUE_NONE == result )
+      {
+         ret = ERROR_FOTA_SUCCESS;
+      }
+      else if(ERROR_FUE_OPERATION_STOP == result)
+      {
+         #ifdef FOTA_DEBUG
+         ASSERT(0);
+         #endif
+         ret = ERROR_FOTA_FLASH_DEVICE;
+      }
+   }
+   return ret;
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_ReadUpdateRecord
+DESCRIPTION
+   FOTA update state information read API
+   download client and update agent use this information to communicate with each other
+PARAMETER
+   NULL
+RETURN
+   0: means pass initialization step (ERROR_FOTA_SUCCESS)
+   < 0: means fail
+      ERROR_FOTA_CUSTOMIZATION: wrong customization
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_ReadUpdateRecord(FOTA_Custom_Update_Info* record)
+{
+   kal_int32       ret     = ERROR_FOTA_SUCCESS;
+   FUE_ERROR_CODE  result  = ERROR_FUE_NONE;
+
+   /* check whether FOTA is initialized */
+   if(UPDATE_STATE_RECORD_ID != FOTA_Update_Ctrl.FOTA_UPDATE_ID)
+   {
+      ret = ERROR_FOTA_NOT_INITIALIZED;
+   }
+   else
+   {
+      result = FUE_NFB_Get_Update_Record(record, fue_dbg_print);
+
+      if(ERROR_FUE_UNRECOVERABLE_ECC == result)
+      {
+         ret = ERROR_FOTA_READ;
+      }
+      else if(ERROR_FUE_OPERATION_STOP == result)
+      {
+        ret = ERROR_FOTA_FLASH_DEVICE;
+      }
+   }
+   return ret;
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Inform_Update_State
+DESCRIPTION
+   Download client use this function to query the result of update process
+PARAMETER
+   NULL
+RETURN
+--------------------------------------------------------------------------------- */
+FOTA_update_result  FOTA_Inform_Update_State(void)
+{
+   FOTA_update_result  ret     = FOTA_UPDATE_NONE;
+   FUE_ERROR_CODE      result  = ERROR_FUE_NONE;
+   FOTA_Custom_Update_Info   upt_info;
+
+   /* check whether FOTA is initialized */
+   if(UPDATE_STATE_RECORD_ID != FOTA_Update_Ctrl.FOTA_UPDATE_ID)
+   {
+      ret = FOTA_UPDATE_NONE;
+   }
+   else
+   {
+      result = FOTA_ReadUpdateRecord(&upt_info);
+
+      if(ERROR_FUE_NONE == result)
+      {
+         /* check customer's state */
+         if( FUE_UA_COMPLETE_PHASE == upt_info.FOTA_test_info1 )
+         {
+            ret = FOTA_UPDATE_SUCCEEDED;
+         }
+         else
+         {
+#if 0 
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+            {
+               ret = FOTA_UPDATE_FAILED;
+            }
+         }
+      }
+      else
+      {
+         ret = FOTA_UPDATE_NONE;
+      }
+   }
+   
+   return ret;
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Start_Download_State
+DESCRIPTION
+   Download client use this function to query the result of update process
+PARAMETER
+   NULL
+RETURN
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_Start_Download_State(void)
+{
+   kal_int32           ret     = ERROR_FOTA_SUCCESS;
+   FOTA_Custom_Update_Info   upt_info;
+
+   if(UPDATE_STATE_RECORD_ID != FOTA_Update_Ctrl.FOTA_UPDATE_ID)
+   {
+      ret = ERROR_FOTA_NOT_INITIALIZED;
+   }
+   else
+   {
+      kal_mem_set(&upt_info,0xff,sizeof(FOTA_Custom_Update_Info));
+      FUE_Start_Download_State();
+      ret = FOTA_WriteUpdateRecord(&upt_info);
+   }
+
+   return ret;
+}
+
+/* ---------------------------------------------------------------------------------
+FUNCTION
+   FOTA_Start_Update_State
+DESCRIPTION
+   Download client use this function to query the result of update process
+PARAMETER
+   NULL
+RETURN
+--------------------------------------------------------------------------------- */
+kal_int32 FOTA_Start_Update_State(void)
+{
+   kal_int32           ret     = ERROR_FOTA_SUCCESS;
+   FOTA_Custom_Update_Info   upt_info;
+
+   if(UPDATE_STATE_RECORD_ID != FOTA_Update_Ctrl.FOTA_UPDATE_ID)
+   {
+      ret = ERROR_FOTA_NOT_INITIALIZED;
+   }
+   else
+   {
+      kal_mem_set(&upt_info,0xff,sizeof(FOTA_Custom_Update_Info));
+      FUE_Start_Package_Verification_State();
+      ret = FOTA_WriteUpdateRecord(&upt_info);
+   }
+
+   return ret;
+}
+
+
+/* --------------------------------------------------------------------------------- *
+ * Flash Generic Access Layer 
+ * --------------------------------------------------------------------------------- */
+#define FOTA_FGAL_READY   (0x59445246)
+kal_uint32 g_FOTA_fgal_state;
+
+#if defined(_NAND_FLASH_BOOTING_) || (defined(__UP_PKG_ON_NAND__) && defined(NAND_SUPPORT))
+
+#if !defined(__NAND_FDM_50__)
+#include "NAND_FDM.h"
+#include "nand_mtd.h"
+#include "nand_mtd_internal.h"
+#else
+#include "NAND_MTD_FDM50.h"
+#include "NAND_DAL.h"
+#include "NAND_MTD_FDM50_internal.h"
+#include "NAND_DAL_internal.h"
+
+extern kal_uint8 IsGoodBlock(void* D, void * Spare);
+#endif /* !__NAND_FDM_50__ */
+
+/* Following functions and variables are located in NAND_MTD.c */
+extern int NFB_ReadPhysicalPage(kal_uint32 PhyBlock, kal_uint32 PhyPage, void * Data);
+extern int NFB_ReadPhysicalSpare(kal_uint32 PhyBlock, kal_uint32 PhyPage, void * Data, kal_bool chksum);
+extern int NFB_ProgramPhysicalPage(kal_uint32 PhyBlock, kal_uint32 PhyPage, void * Data, kal_bool DALRemap);
+extern int NFB_ProgramPhysicalSpare(kal_uint32 PhyBlock, kal_uint32 PhyPage, void * Data, kal_bool chksum, kal_bool DALRemap);
+extern int NFB_ErasePhysicalBlock(kal_uint32 PhyBlock, kal_bool DALRemap);
+extern void get_NFI_bus(void);
+extern void free_NFI_bus(void);
+
+extern int NFBPageSize;
+extern int NFBBlockSize;
+
+#if defined(__NAND_FDM_50__)
+
+extern flash_info_2 Flash_Info;
+
+#else /* NAND FDM 4.x */
+
+extern NAND_FLASH_DRV_DATA  NANDFlashDriveData;
+
+#endif
+
+/* Forward declaration */
+_FGAL_ERROR_CODE FOTA_NAND_Init_func(void);
+_FGAL_ERROR_CODE FOTA_NAND_Page_Read_func(kal_uint32* ptr, kal_uint32 blk, kal_uint32 page);
+_FGAL_ERROR_CODE FOTA_NAND_Query_Info_func(Logical_Flash_info_st* info);
+_FGAL_ERROR_CODE FOTA_NAND_Page_Program_func(kal_uint32* ptr, kal_uint32 blk, kal_uint32 page);
+_FGAL_ERROR_CODE FOTA_NAND_Is_Good_Block_func(kal_uint32 blk);
+_FGAL_ERROR_CODE FOTA_NAND_Mark_Bad_Block_func(kal_uint32 blk);
+_FGAL_ERROR_CODE FOTA_NAND_Erase_Block_func(kal_uint32 blk);
+_FGAL_ERROR_CODE FOTA_NAND_Is_Page_Empty_func(kal_uint32 *buff, kal_uint32 blk, kal_uint32 page);
+_FGAL_ERROR_CODE FOTA_NAND_Lock_Block_func(kal_uint32 blk, kal_bool locked);
+kal_uint32 FOTA_NAND_Block_Size_func(kal_uint32 blk);
+kal_uint32 FOTA_NAND_Block_Index_func(kal_uint32 blk_addr);
+
+/*
+ * Macro definition
+ */
+#define FOTA_NAND_STATE_VALID   (0x5644544D)
+
+#define FOTA_MAX_SPARE_SIZE      (64)
+
+/*
+ * Global variable definition
+ */
+kal_uint32 g_FOTA_NAND_MTD_STATE;
+
+kal_uint32 g_fota_spare_buffer[FOTA_MAX_SPARE_SIZE>>2];
+
+/* For flash generic access layer */
+Flash_GAL_st          FOTA_Nand_Fgal;
+
+/*****************************************************************
+Description : wait for a specific period counted by 32Khz tick.
+Input       : 
+Output      : None
+******************************************************************/
+static void delay32KHzTick(kal_uint32 count)
+{
+	kal_uint32 begin_time = 0;
+	kal_uint32 current_time = 0;
+	
+	begin_time = INT_GetCurrentTime();
+	do
+	{
+	   current_time = INT_GetCurrentTime();
+	   if(current_time > begin_time)
+	   {
+	      if( (current_time-begin_time) > count )
+	         break;
+	   }
+	   else
+	   {
+	      if( (0xFFFFFFFF - begin_time + current_time + 1) > count)
+	         break;
+	   }
+	}while(1);
+}
+
+/*****************************************************************
+Description : set up FGAL structure.
+Input       : 
+Output      : None
+******************************************************************/
+
+
+Flash_GAL_st *FOTA_Setup_FGAL(void)
+{
+   if(FOTA_FGAL_READY == g_FOTA_fgal_state)
+      return &FOTA_Nand_Fgal;
+
+   /* set up FGAL */
+   FOTA_Nand_Fgal.init_drv = FOTA_NAND_Init_func;
+   FOTA_Nand_Fgal.query_info = FOTA_NAND_Query_Info_func;
+   FOTA_Nand_Fgal.read_page = FOTA_NAND_Page_Read_func;
+   FOTA_Nand_Fgal.write_page = FOTA_NAND_Page_Program_func;
+   FOTA_Nand_Fgal.check_block = FOTA_NAND_Is_Good_Block_func;
+   FOTA_Nand_Fgal.mark_bad = FOTA_NAND_Mark_Bad_Block_func;
+   FOTA_Nand_Fgal.erase_block = FOTA_NAND_Erase_Block_func;
+   FOTA_Nand_Fgal.check_empty_page = FOTA_NAND_Is_Page_Empty_func;
+   FOTA_Nand_Fgal.block_size = FOTA_NAND_Block_Size_func;
+   FOTA_Nand_Fgal.block_index = FOTA_NAND_Block_Index_func;
+   FOTA_Nand_Fgal.lock_block = FOTA_NAND_Lock_Block_func;
+
+   /* initialize FGAL driver */
+   FOTA_Nand_Fgal.init_drv();
+
+   g_FOTA_fgal_state = FOTA_FGAL_READY;
+   return &FOTA_Nand_Fgal;
+}
+
+/*****************************************************************
+Description : check whether the provided buffer comes from empty page.
+Input       : 
+Output      : None
+******************************************************************/
+kal_bool FOTA_NAND_MTD_Check_Page_Empty(kal_uint8* page_buffer, kal_uint8* spare_buffer)
+{
+   kal_uint32   spare_len  = 0;
+   kal_uint32   idx = 0, j = 0;
+   kal_uint32*  long_ptr   = NULL;
+   kal_int32    byte_count = 0;
+   kal_int32    long_len   = 0;
+   kal_uint32   page_size  = NFBPageSize;
+
+   switch(page_size)
+   {
+      case 4096:
+         spare_len = 128;
+      break;    
+      case 2048:
+         spare_len = 64;
+      break;
+      case 512:
+         spare_len = 16;
+      break;
+      default:
+         ASSERT(0);
+   }
+   /* compare with 0xFF */
+   if(page_buffer)
+   {
+      long_ptr = (kal_uint32 *)(((kal_uint32)page_buffer+3) & ~(0x03));
+      long_len = ((((kal_uint32)page_buffer+page_size) & ~(0x03)) - (kal_uint32)long_ptr) >> 2;
+      byte_count = (kal_uint32)long_ptr - (kal_uint32)page_buffer;
+      /* chech page content */
+      if(byte_count > 0)
+      {
+         for(j = 0 ; j < byte_count ; j++)
+         {
+            if(page_buffer[j] != 0xFF)
+               return KAL_FALSE;
+         }
+      }
+      for(idx = 0 ; idx < long_len ; idx++)
+      {
+         if(long_ptr[idx] != 0xFFFFFFFF)
+            return KAL_FALSE;
+      }
+      byte_count = page_size - byte_count - (long_len<<2);
+      if(byte_count > 0)
+      {
+         for(j = byte_count ; j > 0 ; j--)
+         {
+            if(page_buffer[page_size-j] != 0xFF)
+               return KAL_FALSE;
+         }
+      }
+   }
+
+   if(spare_buffer)
+   {
+      /* check spare content */
+      long_ptr = (kal_uint32 *)(((kal_uint32)spare_buffer+3) & ~(0x03));
+      long_len = ((((kal_uint32)spare_buffer+spare_len) & ~(0x03)) - (kal_uint32)long_ptr) >> 2;
+      byte_count = (kal_uint32)long_ptr - (kal_uint32)spare_buffer;
+      if(byte_count > 0)
+      {
+         for(j = 0 ; j < byte_count ; j++)
+         {
+            if(spare_buffer[j] != 0xFF)
+               return KAL_FALSE;
+         }
+      }
+      for(idx = 0 ; idx < long_len ; idx++)
+      {
+         if(long_ptr[idx] != 0xFFFFFFFF)
+            return KAL_FALSE;
+      }
+      byte_count = spare_len - byte_count - (long_len<<2);
+      if(byte_count > 0)
+      {
+         for(j = byte_count ; j > 0 ; j--)
+         {
+            if(spare_buffer[page_size-j] != 0xFF)
+               return KAL_FALSE;
+         }
+      }
+   }
+   return KAL_TRUE;;
+}
+
+/*****************************************************************
+Description : check whether the provided buffer comes from spare area of bad block.
+Input       : 
+Output      : None
+******************************************************************/
+void FOTA_NAND_MTD_Set_Spare_Bad_Mark(kal_uint8* spare_buffer)
+{
+   kal_uint8          *byte_ptr  = spare_buffer;
+   kal_bool            word_flag = KAL_FALSE;
+#if !defined(__NAND_FDM_50__)
+   flash_info_struct  *nand_info = &NANDFlashDriveData.flash_info;
+
+   if(IO_ACCESS_16BIT == nand_info->io_width)
+   {
+      word_flag = KAL_TRUE;
+   }
+
+#else
+
+   if(Flash_Info.deviceInfo_CE[0].IOWidth == 16)
+   {
+      word_flag = KAL_TRUE;
+   }
+
+#endif /* __NAND_FDM_50__ */
+
+   if(512 == NFBPageSize)
+   {
+      if(!word_flag)
+      {
+         byte_ptr[5] = 0x0B;
+      }
+      else
+      {
+         byte_ptr[0] = 0x0B;
+         byte_ptr[10] = 0x0B;
+      }
+   }
+   else if((2048 == NFBPageSize)||(4096 == NFBPageSize))
+   {
+      if(!word_flag)
+      {
+         byte_ptr[0] = 0x0B;
+      }
+      else
+      {
+         byte_ptr[0] = 0x0B;
+         byte_ptr[1] = 0x0B;
+      }
+   }
+}
+/*************************************************************************
+* FUNCTION
+*  FOTA_NAND_Init_func
+*
+* DESCRIPTION
+* Initialze NAND flash MTD driver
+ ************************************************************************/
+_FGAL_ERROR_CODE FOTA_NAND_Init_func(void)
+{
+   kal_int32   status = -1;
+
+   status = NFB_ReadPhysicalPage(0xFFFFFFFF, 0xFFFFFFFF, NULL);
+
+   g_FOTA_NAND_MTD_STATE = FOTA_NAND_STATE_VALID;
+
+   #if defined(__NAND_FDM_50__)
+   NFBPageSize = Flash_Info.pageSize;
+   //NFBBlockSize = Flash_Info.pageSize*Flash_Info.blockPage;
+   #endif /* __NAND_FDM_50__ */
+
+   #if defined(__UP_PKG_ON_NAND__)
+   FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start = FOTA_NAND_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE);
+   FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end = FOTA_NAND_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE+FOTA_PACKAGE_STORAGE_SIZE)-1;
+   #endif /* __UP_PKG_ON_NAND__ */
+
+   return ERROR_FGAL_NONE;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NAND_Page_Read_func
+*
+* DESCRIPTION
+* Read one page from NAND flash
+ ************************************************************************/
+_FGAL_ERROR_CODE FOTA_NAND_Page_Read_func(kal_uint32* ptr, kal_uint32 blk, kal_uint32 page)
+{
+   _FGAL_ERROR_CODE   result = ERROR_FGAL_NONE;
+   kal_int32          status = 0;
+   #if !defined(__NFI_VERSION2__) && !defined(__NFI_VERSION3_1__)
+   static kal_uint32  empty_spare[64>>2];
+   #endif /* !__NFI_VERSION2__ && !__NFI_VERSION3_1__*/
+
+   ASSERT( FOTA_NAND_STATE_VALID == g_FOTA_NAND_MTD_STATE);
+
+   status = NFB_ReadPhysicalPage(blk, page, ptr);
+
+   switch(status)
+   {
+      case ERROR_NFB_BAD_BLOCK:
+         result = ERROR_FGAL_BAD_BLOCK;
+         /* should not happen */
+         EXT_ASSERT(0, 0, 0, 0);
+         break;
+      case ERROR_NFB_READ:
+         #if !defined(__NFI_VERSION2__) && !defined(__NFI_VERSION3_1__)
+         /* empty page read will generate ECC failure on NFI version1 */
+         kal_mem_set(empty_spare, 0xFF, 64);
+         NFB_ReadPhysicalSpare(blk, page, empty_spare, KAL_FALSE);
+         if(FOTA_NAND_MTD_Check_Page_Empty((kal_uint8 *)ptr, (kal_uint8 *)empty_spare))
+         {
+            result = ERROR_FGAL_NONE;
+         }
+         else
+         {
+            result = ERROR_FGAL_ECC_FAILURE;
+         }
+         #else /* __NFI_VERSION2__ || __NFI_VERSION3_1__*/
+         result = ERROR_FGAL_ECC_FAILURE;
+         #endif /* !__NFI_VERSION2__ && !__NFI_VERSION3_1__*/
+         break;
+      default:
+         if(NFBPageSize == status)
+            result = ERROR_FGAL_NONE;
+         else
+         {
+            ASSERT(0);
+            result = ERROR_FGAL_OPERATION_RETRY;
+         }
+   }
+   
+   return result;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NAND_Query_Info_func
+*
+* DESCRIPTION
+* Query NAND flash device information
+ ************************************************************************/
+_FGAL_ERROR_CODE FOTA_NAND_Query_Info_func(Logical_Flash_info_st* info)
+{
+   _FGAL_ERROR_CODE   result      = ERROR_FGAL_NONE;
+   kal_uint32         page_size   = 0;
+   kal_uint32         offset      = 0;
+   kal_uint32         pages_per_block = 0;
+   kal_uint32         page_shift = 0;
+#if !defined(__NAND_FDM_50__)
+   flash_info_struct  *nand_info  = &NANDFlashDriveData.flash_info;
+#endif /* __NAND_FDM_50__ */
+
+   ASSERT( FOTA_NAND_STATE_VALID == g_FOTA_NAND_MTD_STATE);
+
+#if defined(__NAND_FDM_50__)
+
+   page_size = Flash_Info.pageSize;
+   if(4096 == page_size)
+   {
+      page_shift = 12;
+   }
+   else if(2048 == page_size)
+   {
+      page_shift = 11;
+   }
+   else if(512 == page_size)
+   {
+      page_shift = 9;
+   }
+   else
+   {
+      /* incorrect device configuration */
+      ASSERT(0);
+   }
+
+   pages_per_block = Flash_Info.blockPage;
+
+   info->Flash_page_size = page_size;
+   info->Flash_block_size = page_size*pages_per_block;
+   info->Flash_io_width = Flash_Info.deviceInfo_CE[0].IOWidth;
+
+#else /* NAND FDM 4 */
+
+   if(PAGE_2K == nand_info->page_type)
+   {
+      page_size = 2048;
+      page_shift = 11;
+   }
+   else if(PAGE_512 == nand_info->page_type)
+   {
+      page_size = 512;
+      page_shift = 9;
+   }
+   else
+   {
+      /* incorrect device configuration */
+      ASSERT(0);
+   }
+
+   pages_per_block = nand_info->pages_per_block;
+
+   info->Flash_page_size = page_size;
+   info->Flash_block_size = page_size*nand_info->pages_per_block;
+   info->Flash_io_width = nand_info->io_width;
+
+#endif
+
+   /* Assumptions: pages per block is power of 2 */
+   info->Flash_offset_shift = INVALID_DWORD;
+   for( offset = 0 ; offset < 32 ; offset++)
+   {
+      if( (1 << offset) == pages_per_block )
+      {
+         info->Flash_offset_shift = offset;
+         info->Flash_block_shift = offset+page_shift;
+         break;
+      }
+   }
+   if(INVALID_DWORD == info->Flash_offset_shift)
+      ASSERT(0); /* incorrect device configuration */
+
+   return result;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NAND_Page_Program_func
+*
+* DESCRIPTION
+* Write one page to NAND flash
+ ************************************************************************/
+_FGAL_ERROR_CODE FOTA_NAND_Page_Program_func(kal_uint32* ptr, kal_uint32 blk, kal_uint32 page)
+{
+   _FGAL_ERROR_CODE   result = ERROR_FGAL_NONE;
+   kal_int32          status = 0;
+
+   ASSERT( FOTA_NAND_STATE_VALID == g_FOTA_NAND_MTD_STATE);
+
+   status = NFB_ProgramPhysicalPage(blk, page, ptr, KAL_TRUE);
+
+   switch(status)
+   {
+      case ERROR_NFB_BAD_BLOCK:
+         result = ERROR_FGAL_BAD_BLOCK;
+         /* should not happen */
+         EXT_ASSERT(0, 0, 0, 0);
+         break;
+      case ERROR_NFB_PROGRAM:
+         result = ERROR_FGAL_WRITE_FAILURE;
+         break;
+      default:
+         if(NFBPageSize == status)
+            result = ERROR_FGAL_NONE;
+         else
+         {
+            ASSERT(0);
+            result = ERROR_FGAL_OPERATION_RETRY;
+         }
+   }
+
+   return result;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NAND_Is_Good_Block_func
+*
+* DESCRIPTION
+* Check whether block is good or bad.
+ ************************************************************************/
+_FGAL_ERROR_CODE FOTA_NAND_Is_Good_Block_func(kal_uint32 blk)
+{
+   _FGAL_ERROR_CODE   result    = ERROR_FGAL_NONE;
+   kal_int32          status    = 0;
+   kal_uint8          *byte_ptr = (kal_uint8 *)g_fota_spare_buffer;
+#if !defined(__NAND_FDM_50__)
+   void *nand_info = (void *)&NANDFlashDriveData;
+#else /* !__NAND_FDM_50__ */
+   void *nand_info = (void *)&Flash_Info;
+#endif 
+
+   ASSERT( FOTA_NAND_STATE_VALID == g_FOTA_NAND_MTD_STATE);
+
+   status = NFB_ReadPhysicalSpare(blk, 0, g_fota_spare_buffer, KAL_FALSE);
+   if(ERROR_NFB_SUCCESS == status)
+   {
+      if(IsGoodBlock(nand_info, byte_ptr) > 0)
+      {
+         status = NFB_ReadPhysicalSpare(blk, 1, g_fota_spare_buffer, KAL_FALSE);
+         if(ERROR_NFB_SUCCESS == status)
+         {
+            if(IsGoodBlock(nand_info, byte_ptr) > 0)
+            {
+               result = ERROR_FGAL_NONE;
+            }
+            else
+            {
+               result = ERROR_FGAL_BAD_BLOCK;
+            }
+         }
+      }
+      else
+      {
+         result = ERROR_FGAL_BAD_BLOCK;
+      }
+   }
+   else
+   {
+      if(ERROR_NFB_READ == status)
+         result = ERROR_FGAL_READ_FAILURE;
+      else
+         ASSERT(0);
+   }
+
+   return result;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NAND_Mark_Bad_Block_func
+*
+* DESCRIPTION
+* Read one page from NAND flash
+ *************************************************************************/
+_FGAL_ERROR_CODE FOTA_NAND_Mark_Bad_Block_func(kal_uint32 blk)
+{
+   _FGAL_ERROR_CODE   result    = ERROR_FGAL_NONE;
+   kal_int32          status    = 0;
+   kal_uint8          *byte_ptr = (kal_uint8 *)g_fota_spare_buffer;
+
+   ASSERT( FOTA_NAND_STATE_VALID == g_FOTA_NAND_MTD_STATE);
+
+   NFB_ErasePhysicalBlock(blk, KAL_TRUE);
+
+   kal_mem_set(g_fota_spare_buffer, 0xFF, FOTA_MAX_SPARE_SIZE);
+   FOTA_NAND_MTD_Set_Spare_Bad_Mark(byte_ptr);
+   
+   status = NFB_ProgramPhysicalSpare(blk, 0, byte_ptr, KAL_FALSE, KAL_TRUE);
+   if(ERROR_NFB_SUCCESS == status)
+   {
+      status = NFB_ProgramPhysicalSpare(blk, 1, byte_ptr, KAL_FALSE, KAL_TRUE);
+   }
+
+   switch(status)
+   {
+      case ERROR_NFB_BAD_BLOCK:
+         result = ERROR_FGAL_BAD_BLOCK;
+         /* should not happen */
+         EXT_ASSERT(0, 0, 0, 0);
+         break;
+      case ERROR_NFB_PROGRAM:
+         result = ERROR_FGAL_WRITE_FAILURE;
+         break;
+      case ERROR_NFB_SUCCESS:
+         result = ERROR_FGAL_NONE;
+         break;
+      default:
+         ASSERT(0);
+         result = ERROR_FGAL_OPERATION_RETRY;
+   }
+
+   return result;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NAND_Erase_Block_func
+*
+* DESCRIPTION
+* Erase one block on NAND flash
+ *************************************************************************/
+_FGAL_ERROR_CODE FOTA_NAND_Erase_Block_func(kal_uint32 blk)
+{
+   kal_uint32         trial = 0;
+   kal_int32          status = -1;
+   _FGAL_ERROR_CODE   result = ERROR_FGAL_NONE;
+
+   ASSERT( FOTA_NAND_STATE_VALID == g_FOTA_NAND_MTD_STATE);
+
+   for(trial = 0 ; trial < 3 ; trial++)
+   {
+      status = NFB_ErasePhysicalBlock(blk, KAL_TRUE);
+      if(ERROR_NFB_ERASE != status)
+         break;
+      delay32KHzTick(1000);
+   }
+
+   switch(status)
+   {
+      case ERROR_NFB_BAD_BLOCK:
+         result = ERROR_FGAL_BAD_BLOCK;
+         /* should not happen */
+         EXT_ASSERT(0, 0, 0, 0);
+         break;
+      case ERROR_NFB_ERASE:
+         result = ERROR_FGAL_ERASE_FAILURE;
+         break;
+      case ERROR_NFB_SUCCESS:
+         result = ERROR_FGAL_NONE;
+         break;
+      default:
+         ASSERT(0);
+         result = ERROR_FGAL_OPERATION_RETRY;
+   }
+
+   return result;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NAND_Is_Page_Empty_func
+*
+* DESCRIPTION
+* Read one page from NAND flash
+ *************************************************************************/
+_FGAL_ERROR_CODE FOTA_NAND_Is_Page_Empty_func(kal_uint32 *buff, kal_uint32 blk, kal_uint32 page)
+{
+   _FGAL_ERROR_CODE   result = ERROR_FGAL_NONE;
+   kal_int32          status = ERROR_NFB_READ;
+   kal_int32          status2 = ERROR_NFB_READ;
+
+   ASSERT( FOTA_NAND_STATE_VALID == g_FOTA_NAND_MTD_STATE);
+
+   kal_mem_set(g_fota_spare_buffer, 0x0, FOTA_MAX_SPARE_SIZE);
+   kal_mem_set(buff, 0x0, NFBPageSize);
+
+   status = NFB_ReadPhysicalPage(blk, page, buff);
+   status2 = NFB_ReadPhysicalSpare(blk, page, g_fota_spare_buffer, KAL_FALSE);
+
+   if( (NFBPageSize == status) && (ERROR_NFB_SUCCESS == status2) )
+   {
+      status = ERROR_NFB_SUCCESS;
+   }
+   else
+   {
+      status = ERROR_NFB_READ;
+   }
+
+   switch(status)
+   {
+      case ERROR_NFB_BAD_BLOCK:
+         result = ERROR_FGAL_BAD_BLOCK;
+         /* should not happen */
+         EXT_ASSERT(0, 0, 0, 0);
+         break;
+      case ERROR_NFB_READ: /* empty page in 28/29 is covered here */
+         if(!FOTA_NAND_MTD_Check_Page_Empty((kal_uint8 *)buff, (kal_uint8 *)g_fota_spare_buffer))
+            result = ERROR_FGAL_NON_EMPTY;
+         break;
+      case ERROR_NFB_SUCCESS:
+         if(!FOTA_NAND_MTD_Check_Page_Empty((kal_uint8 *)buff, (kal_uint8 *)g_fota_spare_buffer))
+            result = ERROR_FGAL_NON_EMPTY_CHECK;
+         break;
+      default:
+         ASSERT(0);
+         result = ERROR_FGAL_OPERATION_RETRY;
+   }
+
+   return result;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NAND_Lock_Block_func
+*
+* DESCRIPTION
+* Lock one block on NAND flash
+ *************************************************************************/
+_FGAL_ERROR_CODE FOTA_NAND_Lock_Block_func(kal_uint32 blk, kal_bool locked)
+{
+   return ERROR_FGAL_NONE;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NAND_Block_Size_func
+*
+* DESCRIPTION
+* Erase one block on NAND flash
+ *************************************************************************/
+kal_uint32 FOTA_NAND_Block_Size_func(kal_uint32 blk)
+{
+   kal_uint32          blk_size   = 0;
+#if !defined(__NAND_FDM_50__)
+   flash_info_struct  *nand_info  = &NANDFlashDriveData.flash_info;
+
+   if(PAGE_2K == nand_info->page_type)
+   {
+      blk_size = 2048*nand_info->pages_per_block;
+   }
+   else if(PAGE_512 == nand_info->page_type)
+   {
+      blk_size = 512*nand_info->pages_per_block;
+   }
+   else
+      ASSERT(0); /* incorrect configuration */
+
+#else
+
+   blk_size = Flash_Info.pageSize*Flash_Info.blockPage;
+
+#endif
+
+   return blk_size;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NAND_Block_Index_func
+*
+* DESCRIPTION
+* Erase one block on NAND flash
+ *************************************************************************/
+kal_uint32 FOTA_NAND_Block_Index_func(kal_uint32 blk_addr)
+{
+   kal_uint32          blk_size   = 0;
+#if !defined(__NAND_FDM_50__)
+   flash_info_struct  *nand_info  = &NANDFlashDriveData.flash_info;
+
+   if(PAGE_2K == nand_info->page_type)
+   {
+      blk_size = 2048*nand_info->pages_per_block;
+   }
+   else if(PAGE_512 == nand_info->page_type)
+   {
+      blk_size = 512*nand_info->pages_per_block;
+   }
+   else
+      ASSERT(0); /* incorrect configuration */
+
+#else
+
+   blk_size = Flash_Info.pageSize*Flash_Info.blockPage;
+
+#endif
+
+   ASSERT(blk_size);/* incorrect device configuration */
+
+   return blk_addr/blk_size;
+}
+
+#elif defined(__EMMC_BOOTING__)
+
+/* For flash generic access layer */
+Flash_GAL_st          FOTA_eMMC_Fgal;
+
+Flash_GAL_st *FOTA_Setup_FGAL(void)
+{
+   if(FOTA_FGAL_READY == g_FOTA_fgal_state)
+      return &FOTA_eMMC_Fgal;
+
+   /* set up FGAL */
+   FOTA_eMMC_Fgal.init_drv = FGAL2FTL_Init;
+   FOTA_eMMC_Fgal.query_info = FGAL2FTL_Query_Info;
+   FOTA_eMMC_Fgal.read_page = FGAL2FTL_Read_Page;
+   FOTA_eMMC_Fgal.write_page = FGAL2FTL_Write_Page;
+   FOTA_eMMC_Fgal.check_block = FGAL2FTL_Is_Good_Block;
+   FOTA_eMMC_Fgal.mark_bad = FGAL2FTL_Mard_Bad_Block;
+   FOTA_eMMC_Fgal.erase_block = FGAL2FTL_Erase_Block;
+   FOTA_eMMC_Fgal.check_empty_page = FGAL2FTL_Is_Empty_Page;
+   FOTA_eMMC_Fgal.block_size = FGAL2FTL_Block_Size;
+   FOTA_eMMC_Fgal.block_index = FGAL2FTL_Block_Index;
+   FOTA_eMMC_Fgal.lock_block = FGAL2FTL_Lock_Block;
+
+   /* initialize FGAL driver */
+   FOTA_eMMC_Fgal.init_drv();
+
+   g_FOTA_fgal_state = FOTA_FGAL_READY;
+   return &FOTA_eMMC_Fgal;
+}
+
+
+#else /* !_NAND_FLASH_BOOTING_ */
+
+#include "custom_MemoryDevice.h"
+#include "DrvFlash.h"
+#include "reg_base.h"
+#include "fue_init.h"
+
+/* Forward declaration */
+_FGAL_ERROR_CODE FOTA_NOR_Init_func(void);
+_FGAL_ERROR_CODE FOTA_NOR_Page_Read_func(kal_uint32* ptr, kal_uint32 blk, kal_uint32 page);
+_FGAL_ERROR_CODE FOTA_NOR_Query_Info_func(Logical_Flash_info_st* info);
+_FGAL_ERROR_CODE FOTA_NOR_Page_Program_func(kal_uint32* ptr, kal_uint32 blk, kal_uint32 page);
+_FGAL_ERROR_CODE FOTA_NOR_Is_Good_Block_func(kal_uint32 blk);
+_FGAL_ERROR_CODE FOTA_NOR_Mark_Bad_Block_func(kal_uint32 blk);
+_FGAL_ERROR_CODE FOTA_NOR_Erase_Block_func(kal_uint32 blk);
+_FGAL_ERROR_CODE FOTA_NOR_Is_Page_Empty_func(kal_uint32 *buff, kal_uint32 blk, kal_uint32 page);
+_FGAL_ERROR_CODE FOTA_NOR_Lock_Block_func(kal_uint32 blk, kal_bool locked);
+kal_uint32 FOTA_NOR_Block_Size_func(kal_uint32 blk);
+kal_uint32 FOTA_NOR_Block_Index_func(kal_uint32 blk_addr);
+
+/* Following functions and variables are located in custom_blconfig.c */
+extern kal_uint32 custom_Block_Size(kal_uint32 nor_addr);
+extern kal_uint32 custom_get_NORFLASH_ROMSpace(void);
+extern kal_uint32 custom_get_NORFLASH_Base(void);
+
+/*
+ * Macro definition
+ */
+#define FOTA_NOR_STATE_VALID   (0x5644544D)
+
+#define FOTA_MAX_SPARE_SIZE      (64)
+
+/*
+ * Global variable definition
+ */
+kal_uint32 g_FOTA_NOR_MTD_STATE;
+/* 
+ * For flash generic access layer 
+ */
+Flash_GAL_st          FOTA_Nor_Fgal;
+
+NOR_FLASH_DRV_Data    NORFlashDriveData;
+NOR_Flash_MTD_Data    FOTA_nor_mtdflash;
+
+
+/* 
+ * External variable reference
+ */
+
+extern NOR_MTD_Driver NORFlashMtd;
+
+
+/*****************************************************************
+Description : acquire FDM synchronization lock.
+Input       : 
+Output      : None
+******************************************************************/
+void retrieve_FDM_lock(void)
+{
+   #if   defined(__NOR_FDM5__)
+
+   extern void nFDM_LOCK(void);
+   nFDM_LOCK();
+
+   #else
+
+   extern void FDM_LOCK(void);
+   FDM_LOCK();
+
+   #endif
+}
+
+/*****************************************************************
+Description : relieve FDM synchronization lock.
+Input       : 
+Output      : None
+******************************************************************/
+void release_FDM_lock(void)
+{
+   #if   defined(__NOR_FDM5__)
+
+   extern void nFDM_UNLOCK(void);
+   nFDM_UNLOCK();
+
+   #else
+
+   extern void FDM_UNLOCK(void);
+   FDM_UNLOCK();
+
+   #endif
+}
+
+/*****************************************************************
+Description : Wait device ready before operation
+Input       : 
+Output      : None
+******************************************************************/
+void FOTA_WaitEraseDone(void)
+{
+   #if defined(__NOR_FDM5__)
+
+   return;
+
+   #else // !__SINGLE_BANK_NOR_FLASH_SUPPORT__ && __NOR_FDM4__
+
+   extern NOR_FLASH_DRV_Data FlashDriveData;
+   extern void WaitEraseDone(NOR_FLASH_DRV_Data * D, kal_uint32 frame_tick);
+   //#define INVALID_BLOCK_INDEX   0xFFFFFFFF
+   if( FlashDriveData.ReclaimBlockID != 0xFFFFFFFF )
+   { 
+      WaitEraseDone(&FlashDriveData,70);
+   }
+   #endif
+}
+
+/*****************************************************************
+Description : set up FGAL structure.
+Input       : 
+Output      : None
+******************************************************************/
+#define FOTA_FGAL_READY   (0x59445246)
+kal_uint32 g_FOTA_fgal_state;
+extern kal_uint8 RandomNum;
+
+Flash_GAL_st *FOTA_Setup_FGAL(void)
+{
+
+   if(FOTA_FGAL_READY == g_FOTA_fgal_state)
+      return &FOTA_Nor_Fgal;
+
+  /* set up FGAL */
+   FOTA_Nor_Fgal.init_drv = FOTA_NOR_Init_func;
+   FOTA_Nor_Fgal.query_info = FOTA_NOR_Query_Info_func;
+   FOTA_Nor_Fgal.read_page = FOTA_NOR_Page_Read_func;
+   FOTA_Nor_Fgal.write_page = FOTA_NOR_Page_Program_func;
+   FOTA_Nor_Fgal.check_block = FOTA_NOR_Is_Good_Block_func;
+   FOTA_Nor_Fgal.mark_bad = FOTA_NOR_Mark_Bad_Block_func;
+   FOTA_Nor_Fgal.erase_block = FOTA_NOR_Erase_Block_func;
+   FOTA_Nor_Fgal.check_empty_page = FOTA_NOR_Is_Page_Empty_func;
+   FOTA_Nor_Fgal.block_size = FOTA_NOR_Block_Size_func;
+   FOTA_Nor_Fgal.block_index = FOTA_NOR_Block_Index_func;
+   FOTA_Nor_Fgal.lock_block = FOTA_NOR_Lock_Block_func;
+
+   /* initialize FGAL driver */
+   FOTA_Nor_Fgal.init_drv();
+
+   g_FOTA_fgal_state = FOTA_FGAL_READY;
+
+
+   return &FOTA_Nor_Fgal;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NOR_Init_func
+*
+* DESCRIPTION
+* Initialze NOR flash MTD driver
+ ************************************************************************/
+
+#if defined(__SERIAL_FLASH__)
+
+extern FlashRegionInfo CMEM_FOTA_NORRegionInfo[];
+
+_FGAL_ERROR_CODE FOTA_NOR_Init_func(void)
+{
+
+   if( (FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE) &&
+       (~((kal_uint32)CMEM_FOTA_NORRegionInfo) == ((NOR_Flash_MTD_Data*)(NORFlashDriveData.MTDData))->Signature) )
+      return ERROR_FGAL_NONE;
+
+   g_FOTA_NOR_MTD_STATE = FOTA_NOR_STATE_VALID;
+
+   /* Initialize MTD data table */
+   CMEM_Init_FOTA();
+
+   /* prepare update package area information */
+   // RegionInfo must be assigned before invoke FOTA_NOR_Block_Index_func
+   FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start = FOTA_NOR_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE);
+   FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end = FOTA_NOR_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE+FOTA_PACKAGE_STORAGE_SIZE)-1;
+
+   NORFlashDriveData.FlashInfo.baseUnlockBlock = FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start;
+   NORFlashDriveData.FlashInfo.endUnlockBlock = FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end;
+
+   NORFlashDriveData.MTDDriver->MountDevice(NORFlashDriveData.MTDData, (void*)&NORFlashDriveData.FlashInfo);
+   /* prepare update package area information */
+   //FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start = FOTA_NOR_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE);
+   //FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end = FOTA_NOR_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE+FOTA_PACKAGE_STORAGE_SIZE)-1;
+   /* TODO: unlock all blocks reserved for update package */
+   return ERROR_FGAL_NONE;
+}
+
+#else // !__COMBO_MEMORY_SUPPORT__ && !__SERIAL_FLASH__
+_FGAL_ERROR_CODE FOTA_NOR_Init_func(void)
+{
+   if( (FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE) &&
+       (~((kal_uint32)NORRegionInfo) == FOTA_nor_mtdflash.Signature) )
+      return ERROR_FGAL_NONE;
+
+   g_FOTA_NOR_MTD_STATE = FOTA_NOR_STATE_VALID;
+   /* Initialize MTD data table */
+   FOTA_nor_mtdflash.Signature = ~((kal_uint32)NORRegionInfo);
+
+   NORFlashDriveData.MTDDriver = &NORFlashMtd;
+   NORFlashDriveData.MTDData = &FOTA_nor_mtdflash;
+
+#ifdef __MTK_TARGET__
+   FOTA_nor_mtdflash.BaseAddr = (BYTE *)INT_RetrieveFlashBaseAddr();
+#endif /* __MTK_TARGET__ */
+
+   FOTA_nor_mtdflash.RegionInfo = (FlashRegionInfo *)NORRegionInfo;
+   /* prepare update package area information */
+   FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start = FOTA_NOR_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE);
+   FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end = FOTA_NOR_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE+FOTA_PACKAGE_STORAGE_SIZE)-1;
+
+   NORFlashDriveData.FlashInfo.baseUnlockBlock = FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start;
+   NORFlashDriveData.FlashInfo.endUnlockBlock = FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end;
+
+   NORFlashDriveData.MTDDriver->MountDevice(NORFlashDriveData.MTDData, (void*)&NORFlashDriveData.FlashInfo);
+   /* prepare update package area information */
+   //FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_start = FOTA_NOR_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE);
+   //FOTA_NFB_Area_Info.m_fota_pkg_area.m_pkg_area_end = FOTA_NOR_Block_Index_func(FOTA_PACKAGE_STORAGE_BASE+FOTA_PACKAGE_STORAGE_SIZE)-1;
+   /* TODO: unlock all blocks reserved for update package */
+   return ERROR_FGAL_NONE;
+}
+#endif //__COMBO_MEMORY_SUPPORT__ || __SERIAL_FLASH__
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NOR_Page_Read_func
+*
+* DESCRIPTION
+* Read one page from NOR flash
+ ************************************************************************/
+_FGAL_ERROR_CODE FOTA_NOR_Page_Read_func(kal_uint32* ptr, kal_uint32 blk, kal_uint32 page)
+{
+   NOR_Flash_MTD_Data *mtdflash = (NOR_Flash_MTD_Data *)NORFlashDriveData.MTDData;
+   _FGAL_ERROR_CODE   result = ERROR_FGAL_NONE;
+   kal_int32          status = 0;
+   kal_uint32         blk_size = 0;
+   kal_uint32         src_addr = 0;
+
+   ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
+   retrieve_FDM_lock();
+
+   FOTA_WaitEraseDone();
+
+   blk_size = BlockSize(mtdflash, blk);
+   ASSERT(page < (blk_size/FOTA_FLASH_MAX_PAGE_SIZE));
+   src_addr = (kal_uint32)BlockAddress(mtdflash, blk) + page*FOTA_FLASH_MAX_PAGE_SIZE;
+   kal_mem_cpy(ptr, (void *)src_addr, FOTA_FLASH_MAX_PAGE_SIZE);
+
+   release_FDM_lock();
+   return result;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NOR_Query_Info_func
+*
+* DESCRIPTION
+* Query NOR flash device information
+* The information is specific for flash area reserved for update package 
+ ************************************************************************/
+_FGAL_ERROR_CODE FOTA_NOR_Query_Info_func(Logical_Flash_info_st* info)
+{
+   _FGAL_ERROR_CODE   result      = ERROR_FGAL_NONE;
+   #if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+   #else
+   info->Flash_page_size = FOTA_FLASH_MAX_PAGE_SIZE;
+   info->Flash_io_width = 16;
+   #endif
+
+   return result;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NOR_Page_Program_func
+*
+* DESCRIPTION
+* Write one page to NOR flash
+ ************************************************************************/
+_FGAL_ERROR_CODE FOTA_NOR_Page_Program_func(kal_uint32* ptr, kal_uint32 blk, kal_uint32 page)
+{
+   _FGAL_ERROR_CODE   result    = ERROR_FGAL_NONE;
+   kal_int32          status    = 0;
+   kal_uint32         blk_size  = 0;
+   kal_uint32         dst_addr  = 0;
+   kal_uint32         src_addr  = (kal_uint32)ptr;
+   kal_uint32         left_len  = FOTA_FLASH_MAX_PAGE_SIZE;
+   kal_uint32         write_len = 0;
+   kal_uint32         pbp_len   = 0;
+   NOR_MTD_Driver     *mtd_drv  = NORFlashDriveData.MTDDriver;
+   NOR_Flash_MTD_Data *mtdflash = (NOR_Flash_MTD_Data *)NORFlashDriveData.MTDData;
+
+   ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
+   blk_size = BlockSize(mtdflash, blk);
+   ASSERT(page < (blk_size/FOTA_FLASH_MAX_PAGE_SIZE));
+
+   MapWindow(mtdflash, blk, 0);
+   //mtdflash->CurrAddr = (BYTE *)BlockAddress(mtdflash, blk);
+
+   dst_addr = (kal_uint32)mtdflash->CurrAddr + page*FOTA_FLASH_MAX_PAGE_SIZE;
+
+   retrieve_FDM_lock();
+
+   FOTA_WaitEraseDone();
+
+
+
+   if(BUFFER_PROGRAM_ITERATION_LENGTH)
+   {
+      pbp_len = BUFFER_PROGRAM_ITERATION_LENGTH<<1;
+   }
+   else
+   {
+      pbp_len = 2;
+   }
+
+   while(left_len)
+   {
+      if(left_len > pbp_len)
+      {
+         write_len = pbp_len;
+      }
+      else
+      {
+         write_len = left_len;
+      }
+
+      status = mtd_drv->ProgramData(mtdflash, (void *)dst_addr, (void *)src_addr, write_len);
+      if(RESULT_FLASH_FAIL == status)
+      {
+         break;
+      }
+      else
+      {
+         left_len -= write_len;
+         dst_addr += write_len;
+         src_addr += write_len;
+      }
+   }
+
+
+   release_FDM_lock();
+
+   if(RESULT_FLASH_FAIL == status)
+   {
+      result = ERROR_FGAL_WRITE_FAILURE;
+   }
+
+   return result;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NOR_Is_Good_Block_func
+*
+* DESCRIPTION
+* Check whether block is good or bad.
+* Always return good since no bad block is allowed in NOR flash
+ ************************************************************************/
+_FGAL_ERROR_CODE FOTA_NOR_Is_Good_Block_func(kal_uint32 blk)
+{
+   ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
+
+   return ERROR_FGAL_NONE;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NOR_Mark_Bad_Block_func
+*
+* DESCRIPTION
+* mark a block as bad, should not be called on NOR flash
+ *************************************************************************/
+_FGAL_ERROR_CODE FOTA_NOR_Mark_Bad_Block_func(kal_uint32 blk)
+{
+   ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
+
+   /* should not happen */
+   EXT_ASSERT(0, 0, 0, 0);
+
+   return ERROR_FGAL_OPERATION_RETRY;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NOR_Erase_Block_func
+*
+* DESCRIPTION
+* Erase one block on NOR flash
+ *************************************************************************/
+_FGAL_ERROR_CODE FOTA_NOR_Erase_Block_func(kal_uint32 blk)
+{
+   kal_uint32         trial = 0;
+   kal_int32          status = -1;
+   _FGAL_ERROR_CODE   result = ERROR_FGAL_NONE;
+   NOR_MTD_Driver     *mtd_drv  = NORFlashDriveData.MTDDriver;
+   NOR_Flash_MTD_Data *mtdflash = (NOR_Flash_MTD_Data *)NORFlashDriveData.MTDData;
+
+   MapWindow(mtdflash, blk, 0);
+
+   ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
+   retrieve_FDM_lock();
+
+   FOTA_WaitEraseDone();
+
+
+
+   status = mtd_drv->EraseBlock(mtdflash, blk);
+
+
+   release_FDM_lock();
+
+   return result;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NOR_Is_Page_Empty_func
+*
+* DESCRIPTION
+* Read one page from NOR flash
+ *************************************************************************/
+_FGAL_ERROR_CODE FOTA_NOR_Is_Page_Empty_func(kal_uint32 *buff, kal_uint32 blk, kal_uint32 page)
+{
+   kal_uint32         *page_ptr = NULL;
+   kal_uint32         blk_size  = 0;
+   kal_uint32           idx     = 0;
+   _FGAL_ERROR_CODE   result    = ERROR_FGAL_NONE;
+   NOR_Flash_MTD_Data *mtdflash = (NOR_Flash_MTD_Data *)NORFlashDriveData.MTDData;
+
+   ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
+   blk_size = BlockSize(mtdflash, blk);
+   ASSERT(page < (blk_size/FOTA_FLASH_MAX_PAGE_SIZE));
+
+   mtdflash->CurrAddr = (BYTE *)BlockAddress(mtdflash, blk);
+   page_ptr = (kal_uint32 *)((kal_uint32)mtdflash->CurrAddr + page*FOTA_FLASH_MAX_PAGE_SIZE);
+
+   retrieve_FDM_lock();
+
+   FOTA_WaitEraseDone();  
+
+   for(idx = 0 ; idx < (FOTA_NOR_FLASH_PAGE_SIZE>>2) ; idx++)
+   {
+      if(*(page_ptr+idx) != INVALID_DWORD)
+      {
+         result = ERROR_FGAL_NON_EMPTY_CHECK;
+         break;
+      }
+   }
+
+   release_FDM_lock();
+
+   if(ERROR_FGAL_NON_EMPTY_CHECK == result)
+   {
+      kal_mem_cpy(buff, page_ptr, FOTA_FLASH_MAX_PAGE_SIZE);
+   }
+
+   return result;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NOR_Lock_Block_func
+*
+* DESCRIPTION
+* Erase one block on NOR flash
+ *************************************************************************/
+_FGAL_ERROR_CODE FOTA_NOR_Lock_Block_func(kal_uint32 blk, kal_bool locked)
+{
+   _FGAL_ERROR_CODE   result = ERROR_FGAL_NONE;
+   kal_uint32         blk_addr = 0;
+   kal_uint32         blk_action = 0;
+   NOR_Flash_MTD_Data *mtdflash = (NOR_Flash_MTD_Data *)NORFlashDriveData.MTDData;
+   NOR_MTD_Driver     *mtd_drv  = NORFlashDriveData.MTDDriver;
+
+   ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
+   blk_addr = (kal_uint32)BlockAddress(mtdflash, blk);
+   if(locked)
+   {
+      blk_action = ACTION_LOCK;
+   }
+   else
+   {
+      blk_action = ACTION_UNLOCK;
+   }
+
+   retrieve_FDM_lock();
+
+   FOTA_WaitEraseDone();
+
+   mtd_drv->LockEraseBlkAddr(mtdflash, (void *)blk_addr, blk_action);
+
+   release_FDM_lock();
+   return ERROR_FGAL_NONE;
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NOR_Block_Size_func
+*
+* DESCRIPTION
+* Erase one block on NAND flash
+ *************************************************************************/
+kal_uint32 FOTA_NOR_Block_Size_func(kal_uint32 blk)
+{
+   NOR_Flash_MTD_Data *mtdflash = (NOR_Flash_MTD_Data *)NORFlashDriveData.MTDData;
+   ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
+
+   return BlockSize((void *)mtdflash, blk);
+}
+
+/*************************************************************************
+* FUNCTION
+*  FOTA_NOR_Block_Index_func
+*
+* DESCRIPTION
+* Erase one block on NAND flash
+ *************************************************************************/
+kal_uint32 FOTA_NOR_Block_Index_func(kal_uint32 blk_addr)
+{
+   NOR_Flash_MTD_Data *mtdflash = (NOR_Flash_MTD_Data *)NORFlashDriveData.MTDData;
+   ASSERT( FOTA_NOR_STATE_VALID == g_FOTA_NOR_MTD_STATE);
+
+   return BlockIndex((void *)mtdflash, blk_addr & (~((kal_uint32)mtdflash->BaseAddr)));
+   //return BlockIndex((void *)mtdflash, blk_addr - FOTA_PACKAGE_STORAGE_BASE);
+}
+
+#endif /* NAND_FLASH_BOOTING */
+
+
+#endif /* __FOTA_DM__ */
diff --git a/mcu/driver/drv/src/icc_sim_test.c b/mcu/driver/drv/src/icc_sim_test.c
new file mode 100644
index 0000000..6c6667e
--- /dev/null
+++ b/mcu/driver/drv/src/icc_sim_test.c
@@ -0,0 +1,252 @@
+#ifdef __SIM_DRV_MULTI_DRV_ARCH__
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+#include "drv_comm.h"
+#include "dma_sw.h"
+#include 	"intrCtrl.h"
+#include "sim_hw.h"
+#include "sim_al.h"
+#include "sim_sw_comm.h"
+
+#include "sim_ca_icc_nagra.h"
+#include "multi_icc_custom.h"
+
+extern sim_ctrlDriver sim_ctrlDriver_MT6302, sim_ctrlDriver_MTK;
+extern kal_uint32	hwCbArray[SIM_DRV_MTK_INTERFACE_NUM];
+extern sim_ctrlDriver *sim_driverTable[];
+
+extern sim_HW_cb	simHWCbArray[];
+
+TIccStatus DalIccInit();
+
+sim_test_function_sim3()
+{
+	TIccStatus IccStatus;
+
+
+		IccStatus = DalIccInit();
+		test_icc();
+
+}
+
+sim_test_function_sim1()
+{
+	sim_power_enum resultVoltage;
+	sim_HW_cb	*hw_cb;
+	usim_status_enum status;
+	kal_uint32 simInterface;
+
+	simInterface = 0;
+	hw_cb = &simHWCbArray[simInterface];
+	status = sim_ctrlDriver_MT6302.reset(UNKNOWN_POWER_CLASS, &resultVoltage, KAL_FALSE, hw_cb);
+	sim_ctrlDriver_MT6302.EOC(hw_cb);
+}
+
+sim_test_function_sim2()
+{
+	sim_power_enum resultVoltage;
+	sim_HW_cb	*hw_cb;
+	usim_status_enum status;
+	kal_uint32 simInterface;
+
+
+
+
+	simInterface = 2;
+	hw_cb = &simHWCbArray[simInterface];
+	status = sim_ctrlDriver_MT6302.reset(UNKNOWN_POWER_CLASS, &resultVoltage, KAL_FALSE, hw_cb);
+	sim_ctrlDriver_MT6302.EOC(hw_cb);
+
+}
+
+sim_test_reset_phone(SIM_ICC_APPLICATION application)
+{
+	sim_power_enum resultVoltage;
+	usim_status_enum status;
+	status = L1sim_Reset_All(UNKNOWN_POWER_CLASS, &resultVoltage, KAL_FALSE, application);
+}
+
+sim_test_phone_selectGSM(SIM_ICC_APPLICATION application)
+{
+	SIM_test_selectGSMFile_multiple(application);
+}
+
+
+#if 0
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#ifdef GEMINI_UT_MORE_RESET_POWEROFF
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+/* under construction !*/
+/* under construction !*/
+#ifdef GEMINI_UT_MORE_RESET_POWEROFF
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+/* under construction !*/
+/* under construction !*/
+#ifdef GEMINI_UT_MORE_RESET_POWEROFF
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#else
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+#endif
+
+init_all_cb2()
+{
+	sim_init_hwCb();
+	DRV_ICC_interface_init(SIM_ICC_APPLICATION_CMMB_SMD);
+	DRV_ICC_interface_init(SIM_ICC_APPLICATION_PHONE1);
+	DRV_ICC_interface_init(SIM_ICC_APPLICATION_PHONE2);
+}
+
+init_all_cb()
+{
+	sim_power_enum resultVoltage;
+	sim_HW_cb	*hw_cb;
+	usim_status_enum status;
+	kal_uint32 simInterface;
+	TIccStatus IccStatus;
+
+#if (2 == SIM_DRV_MTK_INTERFACE_NUM)
+	{
+		simInterface = 1;
+		hw_cb = &simHWCbArray[simInterface];
+		hwCbArray[simInterface] = (kal_uint32)hw_cb;
+		sim_driverTable[simInterface] = &sim_ctrlDriver_MTK;
+		
+		hw_cb->mtk_baseAddr = SIM2_base;
+		hw_cb->mtk_pdnAddr = DRVPDN_CON0;
+		hw_cb->mtk_pdnBit = DRVPDN_CON0_SIM2;
+		hw_cb->mtk_pdnDevice = PDN_SIM2;
+		hw_cb->mtk_dmaMaster = DMA_SIM2;
+		hw_cb->mtk_lisrCode = IRQ_SIM2_CODE;
+		hw_cb->simInterface = simInterface;
+		hw_cb->MT6302Interface = 0xFF;
+		hw_cb->MT6302PeerInterfaceCb = 0x0;
+	}
+#endif
+	{
+		simInterface = 0;
+		hw_cb = &simHWCbArray[simInterface];
+		hwCbArray[simInterface] = (kal_uint32)hw_cb;
+		hw_cb->mtk_baseAddr = SIM_base;
+		hw_cb->mtk_pdnAddr = DRVPDN_CON1;
+		hw_cb->mtk_pdnBit = DRVPDN_CON1_SIM;
+		hw_cb->mtk_pdnDevice = PDN_SIM;
+		hw_cb->mtk_dmaMaster = DMA_SIM;
+		hw_cb->mtk_lisrCode = IRQ_SIM_CODE;
+		hw_cb->simInterface = simInterface;
+		hw_cb->MT6302Interface = 0;
+		hw_cb->MT6302PeerInterfaceCb = &simHWCbArray[2];
+	}
+
+	{
+		simInterface = 2;
+		hw_cb = &simHWCbArray[simInterface];
+		hwCbArray[simInterface] = (kal_uint32)hw_cb;
+		hw_cb->mtk_baseAddr = SIM_base;
+		hw_cb->mtk_pdnAddr = DRVPDN_CON1;
+		hw_cb->mtk_pdnBit = DRVPDN_CON1_SIM;
+		hw_cb->mtk_pdnDevice = PDN_SIM;
+		hw_cb->mtk_dmaMaster = DMA_SIM;
+		hw_cb->mtk_lisrCode = IRQ_SIM_CODE;
+		hw_cb->simInterface = simInterface;
+		hw_cb->MT6302Interface = 1;
+		hw_cb->MT6302PeerInterfaceCb = &simHWCbArray[0];
+	}
+
+	
+}
+
+#define SIM_TEST_FUNCTION_NUMBER_MAX 5
+
+void multiple_sim_test()
+{
+	kal_uint32 testIndex = 0;
+	
+	sim_MT6302_init();
+	init_all_cb2();
+	
+	while(1){
+		switch( (testIndex % SIM_TEST_FUNCTION_NUMBER_MAX)){
+			case 0:
+				sim_test_function_sim3();
+				break;
+			case 1:
+				sim_test_reset_phone(SIM_ICC_APPLICATION_PHONE1);
+				break;
+			case 2:
+				sim_test_reset_phone(SIM_ICC_APPLICATION_PHONE2);
+				break;
+			case 3:
+				sim_test_phone_selectGSM(SIM_ICC_APPLICATION_PHONE1);
+				break;
+			case 4:
+				sim_test_phone_selectGSM(SIM_ICC_APPLICATION_PHONE1);
+				break;
+			default:
+				ASSERT(0);
+		}
+		testIndex ++;
+		kal_sleep_task(20);
+	}
+}
+#endif /*__SIM_DRV_MULTI_DRV_ARCH__*/