[Feature]Upload Modem source code
Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/driver/storage/mc/src/sd2.c b/mcu/driver/storage/mc/src/sd2.c
new file mode 100644
index 0000000..c1b4dca
--- /dev/null
+++ b/mcu/driver/storage/mc/src/sd2.c
@@ -0,0 +1,2414 @@
+/*****************************************************************************
+* 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:
+ * ---------
+ * sd.c
+ *
+ * Project:
+ * --------
+ * Maui_Software
+ *
+ * Description:
+ * ------------
+ * driver functons for SD/MMC
+ *
+ *
+ * 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!
+ *
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#ifndef DRV_MSDC_OFF
+#include "kal_public_api.h" //MSBB change #include "kal_release.h"
+//RHR ADD
+#include "kal_general_types.h"
+//#include "btif_sw.h"
+#include "kal_public_api.h"
+//#include "kal_internal_api.h"
+#include "kal_debug.h"
+#include "kal_public_defs.h"
+//RHR REMOVE
+/*
+//MSBB remove #include "app_buff_alloc.h"
+#include "intrCtrl.h"
+#include "gpio_sw.h"
+#include "init.h"
+*/
+//RHR
+#include "drv_comm.h"
+#include "msdc_reg_adap.h"
+#include "msdc_def.h"
+#include "sd_def.h"
+#include "reg_base.h"
+#include "upll_ctrl.h"
+
+#if defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+T_SDC_HANDLE *gSD2 = &gSD_blk[SD_MSDC2];
+extern MSDC_HANDLE *msdc2_handle;
+extern kal_uint32 MSDC_Sector2[128];
+
+extern kal_uint8 MSDC_GetIOCtrlParam(void);
+extern kal_bool INT_USBBoot(void);
+extern int MSDC_GetCustom(void);
+
+/*************************************************************************
+* FUNCTION
+* SD_Acmd42
+*
+* DESCRIPTION
+* connect/disconnect the 50K Ohm pull-up resistor on CD/DAT3
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+*
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Acmd42_2(kal_bool connect)
+{
+ SDC_CMD_STATUS status;
+
+ // send APP_CMD
+ if((status = SD_Cmd55_2(gSD2->mRCA))!=NO_ERROR)
+ return status;
+ // send cmd6
+ if((status = SD_Send_Cmd_2(SDC_CMD_ACMD42,connect))!=NO_ERROR)
+ return status;
+ //read R1
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ return status;
+
+ gSD2->mCD_DAT3 = KAL_FALSE; // pull-up resistor is disconnected for data trnasfer
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SetMMC40_4bit_high_speed
+*
+* DESCRIPTION
+* Check inserted card is SD or MMC
+*
+* PARAMETERS
+*
+*
+* RETURNS
+* SD_CARD or MMC_CARD
+*
+* GLOBALS AFFECTED
+* gMSDC_Handle
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetMMC40_bus_high_speed_2(void)
+{
+ kal_uint32 clock, hs;
+ #ifdef DRV_MSDC_MT6225_SERIES
+ /*use larger driving current. In mt6225 and mt6227D, IOCON is 32 bit register and DLT cannot be 0*/
+ MSDC_LSD_WriteReg(MSDC_IOCON2,0x36);
+ MSDC_SetIOCONRegDLT2();
+ #else
+ MSDC_LSD_WriteReg(MSDC_IOCON2,0x1B);
+ #endif
+
+ if(SD_SetBlength_2(512)!=NO_ERROR)
+ goto err;
+
+ // read the EXT_CSD
+ if(SD_SendEXTCSD_MMC40_2(MSDC_Sector2) != NO_ERROR)
+ goto err;;
+
+ // set high speed
+ if(gSD2->mCSD.ext_csd->card_type & HS_52M)
+ {
+ // should be 52000
+ //clock = 52000;
+ clock = msdc2_handle->msdc_clock / 2;
+ hs = 1;
+ //MSDC_LSD_WriteReg32(MSDC_IOCON,0x010002FF);
+ MSDC_LSD_ClearBits32(MSDC_CFG2,MSDC_CFG_CRED);;
+
+ }
+ else if(gSD2->mCSD.ext_csd->card_type & HS_26M)
+ {
+ // should be 26000
+ clock = 26000;
+ hs = 1;
+ }
+ else
+ {
+ clock = 13000;
+ hs = 0;
+ }
+ if(hs)
+ {
+ // select proper power class
+ if(SD_Switch_MMC40_2(SET_BYTE,EXT_CSD_POW_CLASS_INDEX,
+ (gSD2->mCSD.ext_csd->pwr_52_360&0xf) ,0) != NO_ERROR)
+ goto err;
+
+ // enable high speed (26M or 52M)
+ if(SD_Switch_MMC40_2(SET_BYTE,EXT_CSD_HIGH_SPPED_INDEX,
+ EXT_CSD_ENABLE_HIGH_SPEED,0) != NO_ERROR)
+ goto err;
+
+ // latch data at falling edge to cover the card driving capability
+ // MSDC_LSD_SetBits32(MSDC_CFG2,MSDC_CFG_RED);
+ }
+
+ msdc2_handle->msdc_clock = MSDC_CLOCK;
+ MSDC_SetClock2(clock);
+
+ #ifdef DRV_MSDC_MT6225_SERIES
+ /*change DLT and set cmd latch at rising edge*/
+ MSDC_LSD_WriteReg(MSDC_IOCON2,0x8036);
+ MSDC_SetIOCONRegDLT2();
+ #endif
+
+ #if 0 // MSDC2 only support 1-bit data
+/* under construction !*/
+ #if defined(MMC40_USE_4BIT_BUS)
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #elif defined(MMC40_USE_8BIT_BUS)
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+ #endif
+
+ if(SD_SendEXTCSD_MMC40_2(MSDC_Sector2) != NO_ERROR)
+ goto err;;
+
+ return NO_ERROR;
+err:
+ return ERR_MMC_BUS_HS_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SD_CheckSDorMMC
+*
+* DESCRIPTION
+* Check inserted card is SD or MMC
+*
+* PARAMETERS
+*
+*
+* RETURNS
+* SD_CARD or MMC_CARD
+*
+* GLOBALS AFFECTED
+* gMSDC_Handle
+*
+*************************************************************************/
+T_MSDC_CARD SD_CheckSDorMMC_2()
+{
+ SDC_CMD_STATUS status;
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ SD_Cmd8_2();
+#endif
+ if((status = SD_Acmd41_SD_2())==NO_ERROR)
+ return msdc2_handle->mMSDC_type; // SD_CARD
+ else if((status = SD_Cmd1_MMC_2())==NO_ERROR)
+ return msdc2_handle->mMSDC_type; // MMC_CARD
+
+ return UNKNOWN_CARD;
+}
+/*************************************************************************
+* FUNCTION
+* SD_SetDefault
+*
+* DESCRIPTION
+* set default values to gSD
+*
+* PARAMETERS
+*
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+void SD_SetDefault_2(void)
+{
+ kal_mem_set(gSD2,0,sizeof(T_SDC_HANDLE));
+ gSD2->mBKLength = 512;
+ gSD2->mRCA = 0;
+ gSD2->mInactive = KAL_FALSE;
+ gSD2->mState = IDLE_STA;
+ gSD2->bus_width = 1;
+ gSD2->mCD_DAT3 = KAL_TRUE;
+}
+
+void SD_Use24M_Clock_2(void)
+{
+ if(msdc2_handle->mMSDC_type == SD_CARD || msdc2_handle->mMSDC_type == SD20_LCS_CARD
+ || msdc2_handle->mMSDC_type == SD20_HCS_CARD)
+ {
+ UPLL_Enable(UPLL_OWNER_MSDC2);
+ MSDC_LSD_SetBits32(MSDC_CFG2, MSDC_CFG_CLKSRC);
+ msdc2_handle->msdc_clock = MSDC_CLOCK_USB;
+ MSDC_SetClock2(MSDC_SD_OP_CLOCK);
+ gSD2->flags |= SD_FLAG_USE_USB_CLK;
+ }
+}
+
+void SD_Use13M_Clock_2(void)
+{
+ MSDC_LSD_ClearBits32(MSDC_CFG2, MSDC_CFG_CLKSRC);
+ msdc2_handle->msdc_clock = MSDC_CLOCK;
+ MSDC_SetClock2(MSDC_OP_CLOCK);
+ gSD2->flags &= ~SD_FLAG_USE_USB_CLK;
+}
+
+
+/*************************************************************************
+* FUNCTION
+* SD_Initialize
+*
+* DESCRIPTION
+* Initial SD controller and card
+*
+* PARAMETERS
+*
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Initialize_2(void)
+{
+ kal_uint32 cid[4],csd[4],scr[4];
+ kal_uint16 rca, iocon;
+ SDC_CMD_STATUS status;
+
+ if(msdc2_handle->mIsInitialized == KAL_TRUE)
+ {
+ return NO_ERROR;
+ }
+ // reset the events
+ kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+ // reset msdc
+ if(MSDC_Reg32(MSDC_CFG2) & MSDC_CFG_RST)
+ {
+ MSDC_LSD_ClearBits32(MSDC_CFG2, MSDC_CFG_RST);
+ }
+ else
+ {
+ RESET_MSDC2();
+ }
+
+ #if defined(DRV_MSDC_MT6225_SERIES)
+ MSDC_LSD_SetBits32(MSDC_CFG2,MSDC_CFG_CRED);
+ #endif
+
+ // set the output driving capability from customization interface
+ iocon = MSDC_SetData(MSDC_IOCON2, 0xff, MSDC_GetIOCtrlParam2());
+ // set pull up the data and cmd
+ BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)2,MSDC_CFG_PRCFG0);
+ BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)2,MSDC_CFG_PRCFG1);
+ BitFieldWrite32((kal_uint32*)MSDC_CFG2,(kal_uint32)2,MSDC_CFG_PRCFG2);
+ // set read timeout x5ms
+ BitFieldWrite32((kal_uint32*)SDC_CFG2,(kal_uint32)40,SDC_CFG_DTOC);
+ //set clock of serial clcok for initialization
+ MSDC_LSD_ClearBits32(MSDC_CFG2, MSDC_CFG_CLKSRC);
+ msdc2_handle->msdc_clock = MSDC_CLOCK;
+ MSDC_SetClock2(MSDC_INI_CLOCK);
+ MSDC_LSD_ClearBits32(SDC_CFG2,SDC_CFG_MDLEN);
+ // initial global sturctures
+ SD_SetDefault_2();
+
+ // send the card to IDLE state
+ if((status = SD_Reset_2())!=NO_ERROR)
+ {
+ goto err;
+ }
+
+ // and validate the OCR (CMD0,CMD1 or ADMD41)
+ if(SD_CheckSDorMMC_2() == UNKNOWN_CARD)
+ {
+ status = ERR_STATUS;
+ goto err;
+ }
+
+ // get CID(CMD2)
+ if((status = SD_GetCID_2(cid))!=NO_ERROR)
+ {
+ goto err;
+ }
+ // get or set RCA(CMD3)
+ if((status = SD_ValidateRCA_2(&rca))!=NO_ERROR)
+ {
+ goto err;
+ }
+ // get CSD and analysis the CSD(CMD9)
+ if((status = SD_GetCSD_2(gSD2->mRCA,csd))!=NO_ERROR)
+ {
+ goto err;
+ }
+ // Set driver stage register DSR to default value (0x0404)(CMD4)
+ if(gSD2->mCSD.dsr_imp)
+ if((status = SD_SetDSR_2())!=NO_ERROR)
+ {
+ //dbg_print("6\r\n");
+ goto err;
+ }
+
+ if(MSDC_GetCustom() & MSDC2_WP)
+ {
+ if((MSDC_Reg(SDC_STA2) & SDC_STA_WP))
+ gSD2->mWPEnabled = KAL_TRUE;
+ }
+ status = SD_SelectCard_2(gSD2->mRCA);
+ if(status == CARD_IS_LOCKED)
+ gSD2->mIsLocked = KAL_TRUE;
+
+ #if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ if(gSD2->flags & SD_FLAG_SD_TYPE_CARD)
+ #else
+ if(msdc2_handle->mMSDC_type == SD_CARD)
+ #endif
+ {
+ SD_Use24M_Clock_2();
+ MSDC_SetIOCONRegDLT2();
+ if((status = SD_ReadSCR_2(scr))!=NO_ERROR)
+ {
+ goto err;
+ }
+ #if 0 // MSDC2 only support 1-bit data
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+/* under construction !*/
+ #endif
+
+ #if !defined(__MSDC_TFLASH_DAT3_1BIT_HOT_PLUG__)
+ if((status = SD_Acmd42_2(KAL_FALSE))!=NO_ERROR)
+ {
+ goto err;
+ }
+ #endif
+
+ if(gSD2->flags & SD_FLAG_CMD6_SUPPORT)
+ {
+ status = SD_SelectHighSpeed_SD11_2();
+ if(status == NO_ERROR)
+ {
+ gSD2->flags |= SD_FLAG_HS_ENABLED;
+ MSDC_LSD_ClearBits32(MSDC_CFG2, MSDC_CFG_CLKSRC);
+ msdc2_handle->msdc_clock = MSDC_CLOCK;
+ MSDC_SetClock(26000);
+ }
+ }
+ }
+ else
+ {
+ if(msdc2_handle->mMSDC_type == MMC_CARD && gSD2->mCSD.spec_ver >= 4)
+ {
+ msdc2_handle->mMSDC_type = MMC40_CARD;
+ if((status = SD_SetMMC40_bus_high_speed_2())!= NO_ERROR)
+ goto err;
+ }
+ else
+ {
+ SD_Use13M_Clock_2();
+ }
+ }
+ status = SD_SetBlength_2(512);
+err:
+ if(status != NO_ERROR)
+ {
+ tst_sys_trace("SD2 mount fail!");
+ SD_SetDefault();
+ msdc2_handle->mIsInitialized = KAL_FALSE;
+ }
+ else
+ {
+ tst_sys_trace("SD2 mount ok!");
+ msdc2_handle->mIsInitialized = KAL_TRUE;
+ }
+ kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+
+ return status ;
+}
+
+static kal_uint32 power2(kal_uint32 num)
+{
+ return 1 << num;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_AnalysisCSD
+*
+* DESCRIPTION
+* Analysis Card Specific Data and store in the member of gSD
+*
+* PARAMETERS
+* csd: input csd for analysis
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+void SD_AnalysisCSD_2(kal_uint32* csd)
+{
+ kal_uint8 *ptr;
+ kal_uint32 c_mult,c_size;
+
+ ptr = (kal_uint8*)csd;
+ c_mult = c_size = 0;
+ // these offsets refer to the spec. of SD and MMC
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.csd_ver, ptr, 126,2);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.tacc,ptr,112,8);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.nsac,ptr,104,8);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.tran_speed,ptr,96,8);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.ccc,ptr,84,12);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.r_blk_len,ptr,80,4);
+ gSD2->mCSD.r_blk_len = power2(gSD2->mCSD.r_blk_len);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.r_blk_part,ptr,79,1);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.w_blk_misali,ptr,78,1);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.r_blk_misali,ptr,77,1);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.dsr_imp,ptr,76,1);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.w_blk_part,ptr,21,1);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.w_blk_len,ptr,22,4);
+ gSD2->mCSD.w_blk_len = power2(gSD2->mCSD.w_blk_len);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.wp_grp_enable,ptr,31,1);
+ // there are some difference of CSD between SD and MMC
+ if(msdc2_handle->mMSDC_type == MMC_CARD)
+ {
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.spec_ver, ptr, 122,4);
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.erase_sec_size_mmc,ptr,42,5);
+ gSD2->mCSD.erase_sec_size_mmc = (gSD2->mCSD.erase_sec_size_mmc+1)*gSD2->mCSD.w_blk_len;
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.erase_grp_size_mmc,ptr,37,5);
+ gSD2->mCSD.erase_grp_size_mmc = (gSD2->mCSD.erase_grp_size_mmc+1)*gSD2->mCSD.erase_sec_size_mmc;
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.wp_grp_size_mmc,ptr,32,5);
+ gSD2->mCSD.wp_grp_size_mmc = (gSD2->mCSD.wp_grp_size_mmc + 1)*gSD2->mCSD.erase_grp_size_mmc;
+ }
+ else // SD_CARD
+ {
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.erase_sec_size_sd,ptr,39,7);
+ gSD2->mCSD.erase_sec_size_sd += 1;
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.wp_prg_size_sd,ptr,32,7);
+ gSD2->mCSD.wp_prg_size_sd = (gSD2->mCSD.wp_prg_size_sd+1) * gSD2->mCSD.erase_sec_size_sd;
+ GetBitFieldN((kal_uint8*)&gSD2->mCSD.erase_blk_en_sd,ptr,46,1);
+ }
+
+ #if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ if(msdc2_handle->mMSDC_type == SD20_HCS_CARD && gSD2->mCSD.csd_ver >= SD_CSD_VER_20)
+ {
+ GetBitFieldN((kal_uint8*)&c_size,ptr,48,22);
+ gSD2->mBKNum = (c_size+1);
+ gSD2->mCSD.capacity = (kal_uint64)gSD2->mBKNum*512*1024;
+ }
+ else
+ #endif
+ {
+ GetBitFieldN((kal_uint8*)&c_mult,ptr,47,3);
+ c_mult = power2(c_mult+2);
+ GetBitFieldN((kal_uint8*)&c_size,ptr,62,12);
+ gSD2->mBKNum = (c_size+1)*c_mult;
+ gSD2->mCSD.capacity = (c_size+1)*c_mult*gSD2->mCSD.r_blk_len;
+ }
+
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_AnalysisCID
+*
+* DESCRIPTION
+* Analysis Card Identificaton and store in the member of gSD
+*
+* PARAMETERS
+* cid: input of card ID for analysis
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+*************************************************************************/
+void SD_AnalysisCID_2(kal_uint32* cid)
+{
+ kal_uint8 i;
+ kal_uint8* pcid;
+ pcid = (kal_uint8*)cid;
+
+ if(msdc2_handle->mMSDC_type == MMC_CARD)
+ {
+ GetBitFieldN((kal_uint8*)&gSD2->mCID.year,pcid,8,4);
+ gSD2->mCID.year += 1997;
+ GetBitFieldN((kal_uint8*)&gSD2->mCID.month,pcid,12,4);
+ GetBitFieldN((kal_uint8*)&gSD2->mCID.psn,pcid,16,32);
+ GetBitFieldN((kal_uint8*)&gSD2->mCID.prv,pcid,48,8);
+ for(i=0;i<6;i++)
+ gSD2->mCID.pnm[i] = *(pcid+7+i);
+ GetBitFieldN((kal_uint8*)&gSD2->mCID.oid,pcid,104,16);
+ GetBitFieldN((kal_uint8*)&gSD2->mCID.mid,pcid,120,8);
+
+ // special case handling
+ {
+ kal_uint8 pnm[] = {0xFF,0xFF,0xFF,0xFF,0x36,0x31};
+ if(gSD2->mCID.mid == 6 && gSD2->mCID.oid == 0 &&
+ !kal_mem_cmp(gSD2->mCID.pnm,pnm,6))
+ {
+ gSD2->flags |= SD_FLAG_MMC_MRSW_FAIL;
+ }
+ }
+ }
+ else // SD_CARD
+ {
+ gSD2->mCID.mid = *(pcid+15);
+ gSD2->mCID.oid = *(pcid+13) + 256*(*(pcid+14));
+ for(i=0;i<5;i++)
+ gSD2->mCID.pnm[i] = *(pcid+8+i);
+ gSD2->mCID.prv = *(pcid+7);
+ //gSD2->mCID.psn = *(kal_uint32*)(pcid+3);
+ gSD->mCID.psn = (*(kal_uint32*)(pcid+4)<<8)|*(pcid+3);
+ gSD2->mCID.month = (kal_uint8)GET_BIT(*(pcid+1),0,BIT_MASK_4);
+ gSD2->mCID.year = GET_BIT(*(pcid+1),4,BIT_MASK_4)+16*GET_BIT(*(pcid+2),0,BIT_MASK_4) + 2000;
+ }
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_AnalysisSCR
+*
+* DESCRIPTION
+* Analysis SD Card Configuration Register and store in the member of gSD
+*
+* PARAMETERS
+* scr: input of scr for analysis
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+* Only for SD card.
+*
+*************************************************************************/
+void SD_AnalysisSCR_2(kal_uint32* scr)
+{
+ kal_uint8 *pscr;
+
+ pscr = (kal_uint8*)scr;
+ gSD2->mSCR.spec_ver = (kal_uint8)GET_BIT(*(pscr),0,BIT_MASK_4);
+ if(gSD2->mSCR.spec_ver > SD_SPEC_101)
+ gSD2->flags |= SD_FLAG_CMD6_SUPPORT;
+ gSD2->mSCR.dat_after_erase = (kal_uint8)GET_BIT(*(pscr+1),7,BIT_MASK_1);
+ gSD2->mSCR.security = (kal_uint8)GET_BIT(*(pscr+1),4,BIT_MASK_3);
+ gSD2->mSCR.bus_width = (kal_uint8)GET_BIT(*(pscr+1),0,BIT_MASK_4);
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_WaitCmdRdyOrTo
+*
+* DESCRIPTION
+* Wait until command ready or timeout
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WaitCmdRdyOrTo_2(void)
+{
+ MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_CMD);
+
+ {
+ volatile kal_uint16 sdc_cmdsta;
+ kal_uint32 t1;
+
+ t1 = drv_get_current_time();
+ while(!(sdc_cmdsta = MSDC_Reg(SDC_CMDSTA2))
+ && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_CMD*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ }
+ MSDC_STOP_TIMER2();
+ MSDC_CLR_INT2();
+ msdc2_handle->cmd_sta = sdc_cmdsta;
+ if(sdc_cmdsta & SDC_CMDSTA_CMDTO)
+ {
+ kal_prompt_trace(MOD_MSDC_HISR,"[MSDC]:cmd timeout");
+ return ERR_CMD_TIMEOUT;
+ }
+ else if(sdc_cmdsta & SDC_CMDSTA_RSPCRCERR)
+ {
+ kal_prompt_trace(MOD_MSDC_HISR,"[MSDC]:cmd crc");
+ return ERR_CMD_RSPCRCERR;
+ }
+ else if(sdc_cmdsta & SDC_CMDSTA_CMDRDY)
+ return NO_ERROR;
+ }
+ if(msdc2_handle->is_timeout)
+ return MSDC_GPT_TIMEOUT_ERR;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_WaitDatRdyOrTo_2
+*
+* DESCRIPTION
+* Wait until data ready or timeout
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WaitDatRdyOrTo_2(void)
+{
+ MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_DAT);
+
+
+ {
+ volatile kal_uint16 sdc_datsta;
+ kal_uint32 t1;
+
+ t1 = drv_get_current_time();
+ while(!(sdc_datsta = MSDC_Reg(SDC_DATSTA2))
+ && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ };
+ MSDC_STOP_TIMER2();
+ MSDC_CLR_INT2();
+ msdc2_handle->dat_sta = sdc_datsta;
+ if(sdc_datsta & SDC_DATSTA_DATTO)
+ {
+ kal_prompt_trace(MOD_MSDC_HISR,"[MSDC]:dat timeout");
+ return ERR_DAT_TIMEOUT;
+ }
+ else if(sdc_datsta & SDC_DATSTA_DATCRCERR)
+ {
+ kal_prompt_trace(MOD_MSDC_HISR,"[MSDC]:dat crc");
+ return ERR_DAT_CRCERR;
+ }
+ else if(sdc_datsta & SDC_DATSTA_BLKDONE)
+ return NO_ERROR;
+ }
+ if(msdc2_handle->is_timeout)
+ return MSDC_GPT_TIMEOUT_ERR;
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SD_WaitCardNotBusy_2
+*
+* DESCRIPTION
+* Wait until card is not busy (R1b)
+*
+* PARAMETERS
+*
+* RETURNS
+* void
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Interrupt driven and polling are both implemented
+*
+*************************************************************************/
+
+SDC_CMD_STATUS SD_WaitCardNotBusy_2(void)
+{
+ kal_uint32 t1;
+
+ t1 = drv_get_current_time();
+ MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_DAT);
+#ifdef MSDC_USE_INT
+ {
+ kal_uint32 flags = 0;
+ if(!msdc2_handle->mIsPresent)
+ return;
+ kal_retrieve_eg_events(msdc2_handle->MSDC_Events,EVENT_SDR1BIRQ,KAL_AND_CONSUME,&flags,KAL_SUSPEND);
+ }
+#else
+ {
+ while(SD_IS_R1B_BUSY_2 && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ };
+ MSDC_CLR_INT2();
+ MSDC_STOP_TIMER2();
+ }
+#endif
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_CheckStatus_2
+*
+* DESCRIPTION
+* Check command status
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_CheckStatus_2()
+{
+ kal_uint32 status;
+
+ MSDC_LSD_ReadReg32(SDC_RESP02,&status);
+ if(status & SDC_CSTA_MASK)
+ ASSERT(0);
+ if((status & SDC_CSTA_MASK)==0 )
+ return NO_ERROR;
+ if(status &SDC_CARD_IS_LOCKED)
+ return CARD_IS_LOCKED;
+
+ return ERR_STATUS;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Send_Cmd_2
+*
+* DESCRIPTION
+* to launch the command packet to the card
+*
+* PARAMETERS
+* 1. cmd: the content of SDC_CMD register
+* 2. arg: the argument(if the command need no argument, fill it with 0)
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* 1. Check if controller is available before launch any commands
+* 2. Maybe add check if card is busy (R1b)
+*************************************************************************/
+SDC_CMD_STATUS SD_Send_Cmd_2(kal_uint32 cmd, kal_uint32 arg)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 t1;
+
+ t1 = drv_get_current_time();
+ MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_CMD);
+ // check the controller is ready (stop transaction will fail)
+ if(cmd != SDC_CMD_CMD12)
+ {
+ while(SD_IS_SDC_BUSY_2 && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ }
+ }
+ else
+ {
+ while(SD_IS_CMD_BUSY_2 && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ }
+ }
+ MSDC_STOP_TIMER2();
+ if(msdc2_handle->is_timeout)
+ return MSDC_GPT_TIMEOUT_ERR;
+
+ MSDC_CLR_INT2();
+ // fill out the argument
+ MSDC_LSD_WriteReg32(SDC_ARG2,arg);
+ // launch the command
+ MSDC_LSD_WriteReg32(SDC_CMD2,cmd);
+ if((status = SD_WaitCmdRdyOrTo_2())!=NO_ERROR)
+ return status;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Reset
+*
+* DESCRIPTION
+* reset all cards to idle state
+*
+* PARAMETERS
+* 1. cmd: the content of SDC_CMD register
+* 2. arg: the argument(if the command need no argument, fill it with 0)
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Reset_2(void)
+{
+ SDC_CMD_STATUS status;
+
+ status = SD_Send_Cmd_2(SDC_CMD_CMD0,SDC_NO_ARG);
+ gSD2->mState = IDLE_STA;
+
+ return status;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Cmd55_2
+*
+* DESCRIPTION
+* APP_CMD: inidicate to the card that the next command is an application specified command
+* rather than a standard command
+*
+* PARAMETERS
+* rca: relative card address
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Cmd55_2(kal_uint16 rca)
+{
+ SDC_CMD_STATUS status;
+
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD55,(kal_uint32)rca<<16))!=NO_ERROR)
+ return status;
+ //read R1
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ return status;
+ //check APP_CMD bit in status register
+ MSDC_LSD_ReadReg32(SDC_RESP02,&status);
+ if(status & SDC_CSTA_MASK)
+ ASSERT(0);
+ if(!(status & R1_APP_CMD_5))
+ return ERR_APPCMD_FAILED;
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SD_Cmd8
+*
+* DESCRIPTION
+* 1. Sends SD Memory Card interface conditions for support larger than 2G cards
+* 2. check if the card is compliant to SD2.0 or higher
+* 3. only performed while at IDLE state.
+*
+* PARAMETERS
+*
+* RETURNS
+*
+* GLOBALS AFFECTED
+* gSD2->mIsCMD8
+*
+*************************************************************************/
+void SD_Cmd8_2(void)
+{
+ kal_uint32 resp;
+
+ if(SD_Send_Cmd_2(SDC_CMD_CMD8,SDC_CMD8_ARG)!=NO_ERROR)
+ {
+ SD_Reset_2();
+ gSD2->mCMD8Resp = SD_CMD8_RESP_NORESP;
+ return;
+ }
+ MSDC_LSD_ReadReg32(SDC_RESP02,&resp);
+ if(resp == SDC_CMD8_ARG)
+ gSD2->mCMD8Resp = SD_CMD8_RESP_VALID;
+ else
+ gSD2->mCMD8Resp = SD_CMD8_RESP_INVALID;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Cmd1_MMC
+*
+* DESCRIPTION
+* asks all cards in idle state to send their OCR in the response on the CMD line
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+* only works for MMC
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Cmd1_MMC_2(void)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 _ocr, ocr_i, t1, t2;
+
+ #if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ if(gSD2->mCMD8Resp == SD_CMD8_RESP_INVALID)
+ return ERR_CMD8_INVALID;
+ ocr_i = (SDC_OCR_DEFAULT|MMC_HIGH_DESITY_CHECK_BIT);
+ #else
+ ocr_i = SDC_OCR_DEFAULT;
+ #endif
+
+ if(msdc2_handle->is_init_timeout == KAL_TRUE)
+ return ERR_R3_OCR_BUSY;
+ t2 = drv_get_current_time();
+ do{
+ t1 = drv_get_current_time();
+ MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_DAT);
+ while((MSDC_IS_BUSY2)
+ && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ };
+ MSDC_STOP_TIMER2();
+ if(msdc2_handle->is_timeout)
+ return MSDC_GPT_TIMEOUT_ERR;
+ MSDC_LSD_WriteReg32(SDC_ARG2,ocr_i);
+ MSDC_LSD_WriteReg32(SDC_CMD2,SDC_CMD_CMD1);
+ if((status = SD_WaitCmdRdyOrTo_2()) != NO_ERROR)
+ {
+ return status;
+ }
+ MSDC_LSD_ReadReg32(SDC_RESP02, &_ocr);
+ if((_ocr & SDC_OCR_DEFAULT) == 0)
+ return ERR_OCR_NOT_SUPPORT;
+ if(!msdc2_handle->mIsPresent)
+ return MSDC_CARD_NOT_PRESENT;
+
+ if(!(_ocr&SDC_OCR_BUSY))
+ {
+ if(drv_get_duration_ms(t2) > MSDC_TIMEOUT_PERIOD_INI)
+ {
+ msdc2_handle->is_init_timeout = KAL_TRUE;
+ break;
+ }
+ if((kal_query_systemInit() == KAL_TRUE)
+#ifdef __TST_WRITE_TO_FILE_ONLY__ /*error recording: considering error recording additionally*/
+ || (KAL_TRUE == INT_QueryExceptionStatus())
+#endif
+ )
+ MSDC_GPTI_BusyWait(30);
+ else
+ kal_sleep_task(7);
+
+ }
+ else
+ break;
+ }while(1);
+
+ if(msdc2_handle->is_init_timeout)
+ return ERR_CMD_TIMEOUT;
+
+ #if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ if((_ocr & MMC_HIGH_DESITY_CHECK_MSK) == MMC_HIGH_DESITY_CHECK_BIT)
+ {
+ gSD2->flags |= SD_FLAG_HCS_SUPPORT;
+ msdc2_handle->mMSDC_type = MMC42_CARD;
+ tst_sys_trace("MMC4.2 or higher");
+ }
+ else
+ #endif
+ msdc2_handle->mMSDC_type = MMC_CARD;
+ gSD2->mInactive = KAL_FALSE;
+ gSD2->mSDC_ocr = _ocr;
+ gSD2->mState = READY_STA;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Acmd41_SD
+*
+* DESCRIPTION
+* asks all cards in idle state to send their OCR in the response on the CMD line
+* OCR: Operation Condition Register
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+* only works for SD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Acmd41_SD_2(void)
+{
+
+ SDC_CMD_STATUS status;
+ kal_uint32 _ocr = 0, ocr_i, t1, t2;
+
+#if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ if(gSD2->mCMD8Resp == SD_CMD8_RESP_NORESP)
+ ocr_i = SDC_OCR_DEFAULT;
+ else if(gSD2->mCMD8Resp == SD_CMD8_RESP_VALID)
+ ocr_i = (SDC_OCR_DEFAULT|SD_ACMD41_HCS);
+ else if(gSD2->mCMD8Resp == SD_CMD8_RESP_INVALID)
+ return ERR_CMD8_INVALID;
+#else
+ ocr_i = SDC_OCR_DEFAULT;
+#endif
+
+ msdc2_handle->is_init_timeout = KAL_FALSE;
+ t2 = drv_get_current_time();
+ do{
+ t1 = drv_get_current_time();
+ MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_CMD);
+ while((MSDC_IS_BUSY2)
+ && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_CMD*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ };
+ MSDC_STOP_TIMER2();
+ if(msdc2_handle->is_timeout)
+ return MSDC_GPT_TIMEOUT_ERR;
+ status=SD_Cmd55_2(SDC_RCA_DEFAULT);
+ if(status != NO_ERROR)
+ {
+ return status;
+ }
+ MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_CMD);
+ t1 = drv_get_current_time();
+ while((MSDC_IS_BUSY2)
+ && MSDC_Check_Card_Present2() && !msdc2_handle->is_timeout)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_CMD*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ };
+ MSDC_STOP_TIMER2();
+ if(msdc2_handle->is_timeout)
+ return MSDC_GPT_TIMEOUT_ERR;
+ MSDC_LSD_WriteReg32(SDC_ARG2,ocr_i);
+ MSDC_LSD_WriteReg32(SDC_CMD2,SDC_CMD_CMD41_SD);
+ if((status = SD_WaitCmdRdyOrTo_2()) != NO_ERROR)
+ {
+ return status;
+ }
+ MSDC_LSD_ReadReg32(SDC_RESP02, &_ocr);
+ if((_ocr & SDC_OCR_DEFAULT) == 0)
+ return ERR_OCR_NOT_SUPPORT;
+ if(!msdc2_handle->mIsPresent)
+ return ERR_CARD_NOT_PRESENT;
+ if(!(_ocr&SDC_OCR_BUSY))
+ {
+ if(drv_get_duration_ms(t2) > MSDC_TIMEOUT_PERIOD_INI)
+ {
+ #ifdef DRV_LSD
+ LSD_ASSERT(0, __LINE__);
+ #endif
+ msdc2_handle->is_init_timeout = KAL_TRUE;
+ break;
+ }
+ if((kal_query_systemInit() == KAL_TRUE)
+#ifdef __TST_WRITE_TO_FILE_ONLY__ /*error recording: considering error recording additionally*/
+ || (KAL_TRUE == INT_QueryExceptionStatus())
+#endif
+ )
+ MSDC_GPTI_BusyWait(30);
+ else
+ kal_sleep_task(7);
+ }
+ else
+ break;
+ }
+ while(1);
+
+ if(msdc2_handle->is_init_timeout)
+ return ERR_R3_OCR_BUSY;
+
+ gSD2->mInactive = KAL_FALSE;
+ gSD2->mSDC_ocr = _ocr;
+ #if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ gSD2->flags |= SD_FLAG_SD_TYPE_CARD;
+ if(_ocr & SD_ACMD41_HCS)
+ {
+ gSD2->flags |= SD_FLAG_HCS_SUPPORT;
+ msdc2_handle->mMSDC_type = SD20_HCS_CARD;
+ tst_sys_trace("SD2.0 or higher");
+ }
+ else if(gSD2->mCMD8Resp == SD_CMD8_RESP_VALID)
+ msdc2_handle->mMSDC_type = SD20_LCS_CARD;
+ else
+ #endif
+ msdc2_handle->mMSDC_type = SD_CARD;
+ gSD2->mState = READY_STA;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_GetCID
+*
+* DESCRIPTION
+* Read Card Identification.
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+*
+*
+*************************************************************************/
+
+// Get CID(CMD2)
+SDC_CMD_STATUS SD_GetCID_2(kal_uint32 Cid[4])
+{
+ int i;
+ SDC_CMD_STATUS status;
+
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD2,SDC_NO_ARG))!=NO_ERROR)
+ return status;
+ //read R2
+ for(i=0;i<4;i++)
+ MSDC_LSD_ReadReg32((SDC_RESP02+i*sizeof(kal_uint32)), &Cid[i]);
+ SD_AnalysisCID_2(Cid);
+ gSD2->mState = IDENT_STA;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_ValidateRCA
+*
+* DESCRIPTION
+* assing or read RCA
+*
+* PARAMETERS
+* pRca: used for input or output RCA
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD
+*
+* NOTE
+* RCA is assinged to MMC card fixed to SDC_RCA_MMC(1)
+*
+*************************************************************************/
+
+// assign or read RCA
+SDC_CMD_STATUS SD_ValidateRCA_2(kal_uint16* pRca)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 resp;
+ kal_uint8 state;
+
+ #if defined(SD_MMC_HIGH_DENSITY_SUPPORT)
+ if(gSD2->flags & SD_FLAG_SD_TYPE_CARD )
+ #else
+ if(msdc2_handle->mMSDC_type == SD_CARD)
+ #endif
+ {
+ //read RCA form card
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD3_SD,SDC_NO_ARG))!=NO_ERROR)
+ return status;
+ //read R6
+ MSDC_LSD_ReadReg32(SDC_RESP02, &resp);
+ *pRca = resp >> 16;
+ gSD2->mRCA =*pRca;
+
+ }
+ else
+ {
+ //assign RCA to card
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD3_MMC,(kal_uint32)SDC_RCA_MMC<<16))!=NO_ERROR)
+ return status;
+
+ //read R1
+ MSDC_LSD_ReadReg32(SDC_RESP02, &resp);
+ SD_GetStatus_2(SDC_RCA_MMC,&resp);
+ state = 0;
+ GetBitFieldN((kal_uint8*)&state,(kal_uint8*)&resp,9,4);
+ if(STBY_STA != state)
+ return ERR_RCA_FAIL;
+ *pRca = gSD2->mRCA = SDC_RCA_MMC;
+ }
+
+ gSD2->mState = STBY_STA;
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SetDSR
+*
+* DESCRIPTION
+* set default value to the DSR
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* SDC_DSR_DEFAULT(0x404)
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetDSR_2(void)
+{
+ return SD_Send_Cmd_2(SDC_CMD_CMD4,(kal_uint32)SDC_DSR_DEFAULT<<16);
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SelectCard
+*
+* DESCRIPTION
+* select/deselect card
+*
+* PARAMETERS
+* rca: relative card address
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SelectCard_2(kal_uint16 rca)
+{
+ SDC_CMD_STATUS status;
+
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD7,(kal_uint32)rca<<16))!=NO_ERROR)
+ return status;
+
+ //read R1b
+ if((status = SD_WaitCardNotBusy_2())!=NO_ERROR)
+ return status;
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ return status;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_GetCSD
+*
+* DESCRIPTION
+* Get CSD from addressed card
+*
+* PARAMETERS
+* rca: relative card address
+* Csd: used for containing read CSD
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_GetCSD_2(kal_uint16 rca, kal_uint32 Csd[4])
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 i;
+
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD9,(kal_uint32)rca<<16))!=NO_ERROR)
+ return status;
+ for(i=0;i<4;i++)
+ {
+ MSDC_LSD_ReadReg32((volatile kal_uint32 *)(SDC_RESP02+i*4), &Csd[i]);
+ }
+ SD_AnalysisCSD_2(Csd);
+
+ return NO_ERROR;
+}
+
+// addressed send CID
+SDC_CMD_STATUS SD_GetAddressedCID_2(kal_uint16 rca, kal_uint32 Cid[4])
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 i;
+
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD10,(kal_uint32)rca<<16))!=NO_ERROR)
+ return status;
+ for(i=0;i<4;i++)
+ {
+ MSDC_LSD_ReadReg32((volatile kal_uint32 *)(SDC_RESP02+i*4), &Cid[i]);
+ }
+ return NO_ERROR;
+}
+
+
+/*************************************************************************
+* FUNCTION
+* SD_StopTrans_2
+*
+* DESCRIPTION
+* Stop Muli-Block operation
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* definition of SD_STOP_SLOW is used for some erroneous card
+*************************************************************************/
+SDC_CMD_STATUS SD_StopTrans_2(kal_bool isTx)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 retry = 0;
+
+ while(retry < 30)
+ {
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD12,SDC_NO_ARG))!=NO_ERROR)
+ {
+ retry ++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ if(retry >= 30)
+ {
+ return status;
+ }
+ if(isTx)
+ SD_WaitCardNotBusy_2();
+
+
+#ifdef SD_STOP_SLOW
+ while(MSDC_Reg(SDC_STA2) & SDC_STA_R1BSY);
+ do{
+ SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&status);
+ }while((status & R1_CUR_STATE) >> 9 != TRAN_STA);
+#endif
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_GetStatus_2
+*
+* DESCRIPTION
+* addressed send status
+*
+* PARAMETERS
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_GetStatus_2(kal_uint16 rca, kal_uint32* resp)
+{
+ SDC_CMD_STATUS status;
+
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD13,(kal_uint32)rca <<16))!=NO_ERROR)
+ return status;
+
+ MSDC_LSD_ReadReg32(SDC_RESP02,resp);
+ if((*resp) & SDC_CSTA_MASK)
+ ASSERT(0);
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SetBlength_2
+*
+* DESCRIPTION
+* set block length
+*
+* PARAMETERS
+* BKLength: block length u want to set
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+* gSD2->mBKLength
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetBlength_2(kal_uint32 BKLength)
+{
+ SDC_CMD_STATUS status;
+
+ // maximal value of block length is 2048
+ if(BKLength > SDC_MAX_BKLENGTH)
+ return ERR_INVALID_BKLENGTH;
+ if(!gSD2->mCSD.r_blk_part && BKLength < gSD2->mCSD.max_r_blk_len )
+ return ERR_INVALID_BKLENGTH;
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD16,BKLength))!=NO_ERROR)
+ return status;
+ //read R1
+ status = SD_CheckStatus_2();
+ // 2. configure the controller
+ gSD2->mBKLength = BKLength;
+ BitFieldWrite32((kal_uint32*)SDC_CFG2,BKLength,SDC_CFG_BLKLEN);
+
+ return NO_ERROR;
+}
+
+
+/*************************************************************************
+* FUNCTION
+* SD_ReadSingleBlock
+*
+* DESCRIPTION
+* 1. read a single block form data_adrs of card to the rxbuffer
+* 2. the block length is set by set block length
+*
+* PARAMETERS
+* data_adrs: starting address to read
+* rxbuffer: as name
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* the size of rxbuffer should be 4*n (n : integer)
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_ReadSingleBlock_2(kal_uint32 data_adrs, kal_uint32* rxbuffer)
+{
+ kal_uint32 count;
+ SDC_CMD_STATUS status;
+
+
+ EnableMSDC_DMA2();
+ count = MSDC_SD_BLOCK_SIZE;
+ MSDC_DMATransferFirst2((kal_uint32)rxbuffer,count,KAL_FALSE);
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD17,data_adrs))!=NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ goto ERR_Exit;
+ status = MSDC_DMATransferFinal2();
+ if(status != NO_ERROR)
+ {
+ goto ERR_Exit;
+ }
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+
+ DisableMSDC_DMA2();
+ MSDC_CLR_FIFO2();
+
+ return NO_ERROR;
+ERR_Exit:
+ {
+ kal_uint32 tmp;
+
+ #ifdef MSDC_USE_INT
+ kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+ #endif
+ DisableMSDC_DMA2();
+ RESET_MSDC2();
+
+ // SD_StopTrans_2(KAL_FALSE);
+ SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&tmp);
+ MSDC_LSD_ReadReg32(SDC_DATSTA2,&tmp);
+ MSDC_CLR_FIFO2();
+ return status;
+ }
+
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_ReadMultiBlock
+*
+* DESCRIPTION
+* read num of blocks into rxbuffer
+*
+* PARAMETERS
+* data_adrs: starting address to read
+* rxbuffer: as name
+* num: number of blocks to read
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_ReadMultiBlock_2(kal_uint32 data_adrs, kal_uint32* rxbuffer, kal_uint32 num)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 j, count;
+ #ifndef MSDC_DMA
+ kal_uint32 i;
+ #endif
+
+ EnableMSDC_DMA2();
+ count = MSDC_SD_BLOCK_SIZE;
+ MSDC_DMATransferFirst2((kal_uint32)rxbuffer,count*num,KAL_FALSE);
+ #ifndef DRV_LSD
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD18,data_adrs))!=NO_ERROR)
+ #else
+ LSD_HostSetBuffer((kal_uint8 *)rxbuffer);
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD18|(num<<20) ,data_adrs))!=NO_ERROR)
+ #endif
+ goto ERR_Exit;
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ goto ERR_Exit;
+ count = MSDC_SD_BLOCK_SIZE;
+ status = MSDC_DMATransferFinal2();
+ if(status != NO_ERROR)
+ goto ERR_Exit;
+
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+
+
+ MSDC_CLR_INT2();
+ DisableMSDC_DMA2();
+
+ if(gSD2->flags & SD_FLAG_MMC_MRSW_FAIL)
+ {
+ kal_uint32 delay = 200;
+ while(delay--);
+ }
+ if((status = SD_StopTrans_2(KAL_FALSE))!=NO_ERROR)
+ {
+ //if((data_adrs/gSD2->mBKLength + j) < gSD2->mBKNum)
+ goto ERR_Exit;
+ }
+ MSDC_CLR_FIFO2();
+ return NO_ERROR;
+
+ERR_Exit:
+
+ #ifdef MSDC_USE_INT
+ kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+ #endif
+ DisableMSDC_DMA2();
+ RESET_MSDC2();
+ SD_StopTrans_2(KAL_FALSE);
+ SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&j);
+ MSDC_LSD_ReadReg32(SDC_DATSTA2,&j);
+ MSDC_CLR_FIFO2();
+ return status;
+
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_WriteSingleBlock
+*
+* DESCRIPTION
+* write a single block
+*
+* PARAMETERS
+* address: starting address to write
+* txbuffer: as name
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* block length is set by Set_Block_Length
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WriteSingleBlock_2(kal_uint32 address, kal_uint32* txbuffer)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 count;
+ kal_uint32 *ptr;
+#if defined(MT6225)
+ kal_bool is_aligned;
+ ECO_VERSION eco;
+ eco = INT_ecoVersion();
+#endif
+
+ if(gSD2->mWPEnabled)
+ return ERR_WRITE_PROTECT;
+ EnableMSDC_DMA2();
+ count = MSDC_SD_BLOCK_SIZE;
+
+ #if defined(MT6225)
+ if(eco <= ECO_E3)
+ {
+ is_aligned = ((kal_uint32)txbuffer%4 == 0);
+ if(is_aligned)
+ {
+ ptr = txbuffer;
+ }
+ else
+ {
+ kal_mem_cpy(MSDC_Sector2, txbuffer, 512);
+ ptr = MSDC_Sector2;
+ }
+ }
+ else
+ {
+ ptr = txbuffer;
+ }
+ #else
+ ptr = txbuffer;
+ #endif
+
+ EnableMSDC_DMA2();
+ count = MSDC_SD_BLOCK_SIZE;
+ MSDC_DMATransferFirst2((kal_uint32)ptr,count,KAL_TRUE);
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD24,address))!=NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ goto ERR_Exit;
+ status = MSDC_DMATransferFinal2();
+ if(status != NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_WaitCardNotBusy_2())!=NO_ERROR)
+ goto ERR_Exit;
+ DisableMSDC_DMA2();
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+
+
+ return NO_ERROR;
+ERR_Exit:
+ {
+ kal_uint32 tmp;
+
+ #ifdef MSDC_USE_INT
+ kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+ #endif
+ DisableMSDC_DMA2();
+ RESET_MSDC2();
+ SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&tmp);
+ MSDC_LSD_ReadReg32(SDC_DATSTA2,&tmp);
+ return status;
+ }
+
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_WriteMultiBlock
+*
+* DESCRIPTION
+* write num blocks starting at address
+*
+* PARAMETERS
+* address: starting address to write
+* txbuffer: as name
+* num: number of blocks to write
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* block length is set by Set_Block_Length
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_WriteMultiBlock_2(kal_uint32 address, kal_uint32* txbuffer, kal_uint32 num)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 count;
+ kal_uint32 *ptr;
+ #if defined(MT6225)
+ kal_bool is_aligned, dma_issue;
+ ECO_VERSION eco;
+ eco = INT_ecoVersion();
+ if(eco <= ECO_E3)
+ dma_issue = KAL_TRUE;
+ #endif
+
+ if(gSD2->mWPEnabled)
+ return ERR_WRITE_PROTECT;
+ EnableMSDC_DMA2();
+ count = MSDC_SD_BLOCK_SIZE;
+ #if defined(MT6225)
+ if(dma_issue)
+ {
+ is_aligned = ((kal_uint32)txbuffer%4 == 0);
+ if(is_aligned)
+ {
+ MSDC_DMATransferFirst2((kal_uint32)txbuffer,count*num,KAL_TRUE);
+ }
+ else
+ {
+ kal_mem_cpy(MSDC_Sector2, txbuffer, 512);
+ ptr = txbuffer;
+ MSDC_DMATransferFirst2((kal_uint32)MSDC_Sector2,count,KAL_TRUE);
+ }
+ }
+ else
+ {
+ MSDC_DMATransferFirst2((kal_uint32)txbuffer,count*num,KAL_TRUE);
+ }
+ #elif defined(MSDC_MULTI_BLOCK_WRITE)
+ MSDC_DMATransferFirst2((kal_uint32)txbuffer,count*num,KAL_TRUE);
+ #else
+ ptr = txbuffer;
+ MSDC_DMATransferFirst2((kal_uint32)ptr,count,KAL_TRUE);
+ #endif
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD25,address))!=NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ goto ERR_Exit;
+
+ #if defined(MT6225)
+ if(dma_issue)
+ {
+ if(is_aligned)
+ {
+ status = MSDC_DMATransferFinal2();
+ if(status != NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+ }
+ else
+ {
+ kal_uint32 j;
+
+ for(j=0;j<num;j++)
+ {
+ if(msdc2_handle->mIsPresent == KAL_FALSE)
+ {
+ status = ERR_CARD_NOT_PRESENT;
+ goto ERR_Exit;
+ }
+ if(j!=0)
+ {
+ kal_mem_cpy(MSDC_Sector2, ptr, 512);
+ MSDC_DMATransferFirst2((kal_uint32)MSDC_Sector2,count,KAL_TRUE);
+ }
+ status = MSDC_DMATransferFinal2();
+ ptr += MSDC_SD_BLOCK_SIZE;
+ if(status != NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+ }
+ }
+ }
+ else
+ {
+ status = MSDC_DMATransferFinal2();
+ if(status != NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+ }
+ #elif defined(MSDC_MULTI_BLOCK_WRITE)
+ status = MSDC_DMATransferFinal2();
+ if(status != NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+ #else // not MT6225
+ {
+ kal_uint32 j;
+
+ for(j=0;j<num;j++)
+ {
+ if(msdc2_handle->mIsPresent == KAL_FALSE)
+ {
+ status = ERR_CARD_NOT_PRESENT;
+ goto ERR_Exit;
+ }
+ if(j!=0)
+ {
+ MSDC_DMATransferFirst2((kal_uint32)ptr,count,KAL_TRUE);
+ }
+ status = MSDC_DMATransferFinal2();
+ ptr += MSDC_SD_BLOCK_SIZE;
+ if(status != NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+ }
+
+ }
+ #endif // MT6225
+
+ DisableMSDC_DMA2();
+ if((status = SD_StopTrans_2(KAL_TRUE))!=NO_ERROR)
+ goto ERR_Exit;
+
+ MSDC_CLR_INT2();
+
+ return NO_ERROR;
+ERR_Exit:
+ {
+ kal_uint32 tmp;
+
+ DisableMSDC_DMA2();
+ RESET_MSDC2();
+ SD_StopTrans_2(KAL_TRUE);
+ SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&tmp);
+ MSDC_LSD_ReadReg32(SDC_DATSTA2,&tmp);
+ return status;
+ }
+
+}
+/*************************************************************************
+* FUNCTION
+* SD_SetBusWidth
+*
+* DESCRIPTION
+* ACMD6: set the data width 00 for 1 bit, 10 for 4 bits
+*
+* PARAMETERS
+* width: indicate the bus width
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Not every card support 4-bits bus
+* only for SD
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetBusWidth_2(SD_BITWIDTH width)
+{
+ SDC_CMD_STATUS status;
+
+ // check if card support 4 bits bus
+ if((width == BIT_4W) && !(gSD2->mSCR.bus_width&0x04))
+ return ERR_NOT_SUPPORT_4BITS;
+ // send APP_CMD
+ if((status = SD_Cmd55_2(gSD2->mRCA))!=NO_ERROR)
+ return status;
+ // send cmd6
+ if((status = SD_Send_Cmd_2(SDC_CMD_ACMD6,width))!=NO_ERROR)
+ return status;
+ //read R1
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ return status;
+ // set the controler MDLEN to enalbe 4bits bus width
+ MSDC_LSD_SetBits32(SDC_CFG2,SDC_CFG_MDLEN);
+ gSD2->bus_width = 4;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_ReadSCR
+*
+* DESCRIPTION
+* ACMD51: read the SD Configuration Register(8bytes block read)
+*
+* PARAMETERS
+* scr: used for store SCR
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* Make sure the size of SCR is 8 bytes
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_ReadSCR_2(kal_uint32* scr)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 blklen,i, t1;
+
+ ASSERT((kal_uint32)scr % 4 == 0);
+ // save the original block length
+ blklen = gSD2->mBKLength;
+ // set block length(MSDC_CFG2)
+ if((status = SD_SetBlength_2(8))!=NO_ERROR)
+ return status;
+ // send APP_CMD
+ if((status = SD_Cmd55_2(gSD2->mRCA))!=NO_ERROR)
+ return status;
+ // send command
+ if((status = SD_Send_Cmd_2(SDC_CMD_ACMD51,SDC_NO_ARG))!=NO_ERROR)
+ return status;
+ //read R1
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ return status;
+ // read data(8bytes)
+#ifndef DRV_LSD
+ // failed to use DMA with burst mode
+ t1 = drv_get_current_time();
+ MSDC_START_TIMER2(MSDC_TIMEOUT_PERIOD_DAT);
+ for(i=0;i<2;)
+ {
+ if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
+ msdc2_handle->is_timeout = KAL_TRUE;
+ if(!msdc2_handle->mIsPresent)
+ return ERR_CARD_NOT_PRESENT;
+ if(msdc2_handle->is_timeout)
+ return MSDC_GPT_TIMEOUT_ERR;
+ if(!MSDC_IS_FIFO_EMPTY2)
+ {
+ *(kal_uint32*)(scr+i) = MSDC_Reg32(MSDC_DAT2);
+ i++;
+ }
+ }
+#else
+ LSD_readFIFO(scr ,2);
+
+#endif
+ MSDC_STOP_TIMER2();
+ // analysis scr
+ SD_AnalysisSCR(scr);
+ // clean EVENT_SDDATIRQ
+ #ifdef MSDC_USE_INT
+ kal_set_eg_events(msdc2_handle->MSDC_Events, 0, KAL_AND);
+ #endif
+ MSDC_CLR_FIFO2();
+ return NO_ERROR;
+
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SetPreEraseBlk
+*
+* DESCRIPTION
+* ACMD23: set the number of write blocksto be pre-erased before writing
+* used for faster multiple Block Write
+*
+* PARAMETERS
+* num: used for storing number of blocks during multi-block operation
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SetPreEraseBlk_2(kal_uint32 num)
+{
+ SDC_CMD_STATUS status;
+
+ //[22:0] number of blocks
+ num &= 0x003FFF;
+ // send APP_CMD
+ if((status = SD_Cmd55_2(gSD2->mRCA))!=NO_ERROR)
+ return status;
+ // send CMD23
+ if((status = SD_Send_Cmd_2(SDC_CMD_ACMD23,num))!=NO_ERROR)
+ return status;
+ //read R1
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ return status;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_EraseCmdClass
+*
+* DESCRIPTION
+* groups of erase commands including CMD32 ~CMD38
+*
+* PARAMETERS
+* cmd: indicate which command to execute
+* address: starting address wiht write protection
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+* CMD34~CMD37 are only for MMC
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_EraseCmdClass_2(kal_uint32 cmd ,kal_uint32 address)
+{
+ SDC_CMD_STATUS status;
+
+ if(cmd != SDC_CMD_CMD38)
+ {
+ if((status = SD_Send_Cmd_2(cmd,address))!=NO_ERROR)
+ return status;
+ }
+ else if((status = SD_Send_Cmd_2(cmd,SDC_NO_ARG))!=NO_ERROR)
+ return status;
+
+ //read R1
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ return status;
+
+ if(cmd == SDC_CMD_CMD38)
+ {
+ SD_WaitCardNotBusy_2();
+ do{
+ SD_GetStatus_2(gSD2->mRCA,(kal_uint32*)&status);
+ if(msdc2_handle->mIsPresent == KAL_FALSE)
+ break;
+ }while(CurState(status)!= TRAN_STA);
+ }
+
+ return NO_ERROR;
+}
+/*************************************************************************
+* FUNCTION
+* SD_Switch_MMC40
+*
+* DESCRIPTION
+* CMD6: set the command set or write to the EXT_CSD (for MMC4.0)
+*
+* PARAMETERS
+* access: access mode
+* index: index to EXT_CSD
+* value: value to write to EXT_CSD
+* set: selected command set
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Switch_MMC40_2(kal_uint8 access, kal_uint8 index, kal_uint8 value, kal_uint8 set)
+{
+ SDC_CMD_STATUS status;
+ kal_uint32 arg = 0;
+
+ arg = (access<<24)|(index<<16)|(value<<8)|set;
+ // send command
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD6_MMC40,arg))!=NO_ERROR)
+ return status;
+ //read R1
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ return status;
+
+ return NO_ERROR;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_SendEXTCSD_MMC40
+*
+* DESCRIPTION
+* CMD8: read the content of EXT_CSD register
+*
+* PARAMETERS
+* kal: access mode
+* index: index to EXT_CSD
+* value: value to write to EXT_CSD
+* set: selected command set
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SendEXTCSD_MMC40_2(kal_uint32* rxbuffer)
+{
+ SDC_CMD_STATUS status;
+ kal_bool retry_4bit = KAL_FALSE;
+
+start:
+ // read the block of 512 bytes (make sure the rxbuffer is 4 byte aligned)
+ EnableMSDC_DMA2();
+ MSDC_DMATransferFirst2((kal_uint32)rxbuffer,128,KAL_FALSE);
+#ifdef DRV_LSD
+ LSD_HostSetBuffer((kal_uint8 *)rxbuffer);
+#endif
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD8_MMC40,SDC_NO_ARG))!=NO_ERROR)
+ goto ERR_Exit;
+ //read R1
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ goto ERR_Exit;
+ // read the block of 512 bytes (make sure the rxbuffer is 4 byte aligned)
+ status = MSDC_DMATransferFinal2();
+ if(status != NO_ERROR)
+ goto ERR_Exit;
+ if((status = SD_WaitDatRdyOrTo_2())!=NO_ERROR)
+ goto ERR_Exit;
+
+ DisableMSDC_DMA2();
+ MSDC_CLR_FIFO2();
+ gSD2->mCSD.ext_csd = (T_EXT_CSD_MMC40 *)rxbuffer;
+ return NO_ERROR;
+
+ERR_Exit:
+
+ if(retry_4bit == KAL_FALSE)
+ {
+ retry_4bit = KAL_TRUE;
+ MSDC_LSD_SetBits32(SDC_CFG2,SDC_CFG_MDLEN);
+ gSD2->bus_width = 4;
+ goto start;
+ }
+ MSDC_LSD_ClearBits32(SDC_CFG2,SDC_CFG_MDLEN);
+ gSD2->bus_width = 1;
+ DisableMSDC_DMA2();
+ MSDC_CLR_FIFO2();
+ RESET_MSDC2();
+
+ return status;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Switch_SD11
+*
+* DESCRIPTION
+* CMD6: switch command to query and select the specific functions. (SD1.1 or later)
+* PARAMETERS
+* arg: argument
+* resp: buffer to contain the ther 64 bytes status information
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_Switch_SD11_2(kal_uint32 arg, T_SWITCH_STATUS* info)
+{
+ SDC_CMD_STATUS status = NO_ERROR;
+
+ BitFieldWrite32((kal_uint32*)SDC_CFG2,SD_CMD6_RESP_LEN,SDC_CFG_BLKLEN);
+ EnableMSDC_DMA2();
+ MSDC_DMATransferFirst2((kal_uint32)info,(SD_CMD6_RESP_LEN>>2),KAL_FALSE);
+ if((status = SD_Send_Cmd_2(SDC_CMD_CMD6_SD11,arg))!=NO_ERROR)
+ goto exit;
+ if((status = SD_CheckStatus_2())!=NO_ERROR)
+ goto exit;
+ status = MSDC_DMATransferFinal2();
+
+exit:
+ DisableMSDC_DMA2();
+ return status;
+}
+
+/*************************************************************************
+* FUNCTION
+* SD_Switch_SD11
+*
+* DESCRIPTION
+* Enable the high speed interface to support up to 50M Hz clock
+*
+* PARAMETERS
+* arg: argument
+* resp: buffer to contain the ther 64 bytes status information
+*
+* RETURNS
+* SDC_CMD_STATUS
+*
+* GLOBALS AFFECTED
+*
+* NOTE
+*
+*************************************************************************/
+SDC_CMD_STATUS SD_SelectHighSpeed_SD11_2(void)
+{
+ SDC_CMD_STATUS status;
+ T_SWITCH_STATUS *p = (T_SWITCH_STATUS*)MSDC_Sector2;
+
+ if((status = SD_Switch_SD11(SD_CMD6_QUERY_HIGH_SPEED, p))!=NO_ERROR)
+ return status;
+ if(p->max_current == 0)
+ return ERR_SD_HS_FAIL;
+ if((p->group1_info & (1 << SD_FUNC_HIGH_SPEED)) &&
+ (p->group1_result == SD_FUNC_HIGH_SPEED))
+ {
+ if((status = SD_Switch_SD11(SD_CMD6_SELECT_HIGH_SPEED, p))!=NO_ERROR)
+ return status;
+ if(p->max_current == 0)
+ return ERR_SD_HS_FAIL;
+ if(p->group1_result == SD_FUNC_HIGH_SPEED)
+ gSD2->flags |= SD_FLAG_HS_SUPPORT;
+ }
+ else
+ return ERR_SD_HS_FAIL;
+
+
+ return NO_ERROR;
+}
+
+kal_bool MSDC_ModuleTest_Report_2(void)
+{
+ return msdc2_handle->mIsInitialized;
+}
+
+#endif // defined(__MSDC2_SD_MMC__) || defined(__MSDC2_SD_SDIO__)
+
+#endif //DRV_MSDC_OFF