[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/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__*/