diff -bur mmcsdlib/hs_mmcsdlib.c mmcsdlib.new/hs_mmcsdlib.c
--- mmcsdlib/hs_mmcsdlib.c	2013-07-11 17:23:13.000000000 -0400
+++ mmcsdlib.new/hs_mmcsdlib.c	2014-04-04 10:13:50.000000000 -0400
@@ -105,16 +105,19 @@
     HSMMCSDLinesReset(ctrl->memBase, HS_MMCSD_ALL_RESET);
 
     /* Set supported voltage list */
-    HSMMCSDSupportedVoltSet(ctrl->memBase, HS_MMCSD_SUPPORT_VOLT_1P8 |
-                                                HS_MMCSD_SUPPORT_VOLT_3P0);
+    //HSMMCSDSupportedVoltSet(ctrl->memBase, HS_MMCSD_SUPPORT_VOLT_1P8 |
+    //                                            HS_MMCSD_SUPPORT_VOLT_3P0);
+
+    HSMMCSDSupportedVoltSet(ctrl->memBase, HS_MMCSD_SUPPORT_VOLT_1P8 |HS_MMCSD_SUPPORT_VOLT_3P3);
+
 
     HSMMCSDSystemConfig(ctrl->memBase, HS_MMCSD_AUTOIDLE_ENABLE);
 
     /* Set the bus width */
-    HSMMCSDBusWidthSet(ctrl->memBase, HS_MMCSD_BUS_WIDTH_1BIT );
+    HSMMCSDBusWidthSet(ctrl->memBase, HS_MMCSD_BUS_WIDTH_4BIT ); /////////////////////////////////////////////////////////////////
 
     /* Set the bus voltage */
-    HSMMCSDBusVoltSet(ctrl->memBase, HS_MMCSD_BUS_VOLT_3P0);
+    HSMMCSDBusVoltSet(ctrl->memBase, HS_MMCSD_BUS_VOLT_3P3);
 
     /* Bus power on */
     status = HSMMCSDBusPower(ctrl->memBase, HS_MMCSD_BUS_POWER_ON);
@@ -239,10 +242,15 @@
     {
            HSMMCSDBusWidthSet(ctrl->memBase, HS_MMCSD_BUS_WIDTH_1BIT);
     }
-    else
+
+    else if (busWidth == SD_BUS_WIDTH_4BIT)
     {
            HSMMCSDBusWidthSet(ctrl->memBase, HS_MMCSD_BUS_WIDTH_4BIT);
     }
+    else
+    {
+    	HSMMCSDBusWidthSet(ctrl->memBase, HS_MMCSD_BUS_WIDTH_8BIT);
+    }
 }
 /**
  * \brief   Set output bus frequency
diff -bur mmcsdlib/include/mmcsd_proto.h mmcsdlib.new/include/mmcsd_proto.h
--- mmcsdlib/include/mmcsd_proto.h	2013-07-11 17:23:13.000000000 -0400
+++ mmcsdlib.new/include/mmcsd_proto.h	2014-04-07 16:19:50.000000000 -0400
@@ -79,7 +79,7 @@
 	unsigned int idx;
 	unsigned int flags;
 	unsigned int arg;
-	signed char *data;
+	unsigned char *data;
 	unsigned int nblks;
 	unsigned int rsp[4];
 }mmcsdCmd;
@@ -124,6 +124,11 @@
 #define SD_CMDRSP_WRITE			BIT(8)
 
 
+#define SD_CMDRSP_R1			(0)
+#define SD_CMDRSP_R1b			(0 | SD_CMDRSP_BUSY)
+#define SD_CMDRSP_R2			(SD_CMDRSP_136BITS)
+#define SD_CMDRSP_R3			(SD_CMDRSP_R1)
+
 
 /* SD voltage enumeration as per VHS field of the interface command */
 #define SD_VOLT_2P7_3P6                 (0x000100u)
@@ -185,6 +190,7 @@
 #define SD_VERSION_2P0		2
 #define SD_BUS_WIDTH_1BIT	1
 #define SD_BUS_WIDTH_4BIT	4
+#define SD_BUS_WIDTH_8BIT	8
 
 /* Helper macros */
 /* Note card registers are big endian */
diff -bur mmcsdlib/mmcsd_proto.c mmcsdlib.new/mmcsd_proto.c
--- mmcsdlib/mmcsd_proto.c	2013-07-11 17:23:13.000000000 -0400
+++ mmcsdlib.new/mmcsd_proto.c	2014-04-08 12:48:58.000000000 -0400
@@ -44,8 +44,328 @@
 #include "string.h"
 #include "uartStdio.h"
 #include "cache.h"
+#include "hs_mmcsd.h"
+
+#define DATA_RESPONSE_WIDTH       (512)
+
+/*
+ * EXT_CSD switch cmd macros
+ */
+
+#define EXT_CSD_FLUSH_CACHE             32      /* W */
+#define EXT_CSD_CACHE_CTRL              33      /* R/W */
+#define EXT_CSD_POWER_OFF_NOTIFICATION  34      /* R/W */
+#define EXT_CSD_PACKED_FAILURE_INDEX    35      /* RO */
+#define EXT_CSD_PACKED_CMD_STATUS       36      /* RO */
+#define EXT_CSD_EXP_EVENTS_STATUS       54      /* RO, 2 bytes */
+#define EXT_CSD_EXP_EVENTS_CTRL         56      /* R/W, 2 bytes */
+#define EXT_CSD_DATA_SECTOR_SIZE        61      /* R */
+#define EXT_CSD_GP_SIZE_MULT            143     /* R/W */
+#define EXT_CSD_PARTITION_ATTRIBUTE     156     /* R/W */
+#define EXT_CSD_PARTITION_SUPPORT       160     /* RO */
+#define EXT_CSD_HPI_MGMT                161     /* R/W */
+#define EXT_CSD_RST_N_FUNCTION          162     /* R/W */
+#define EXT_CSD_BKOPS_EN                163     /* R/W */
+#define EXT_CSD_BKOPS_START             164     /* W */
+#define EXT_CSD_SANITIZE_START          165     /* W */
+#define EXT_CSD_WR_REL_PARAM            166     /* RO */
+#define EXT_CSD_RPMB_MULT               168     /* RO */
+#define EXT_CSD_BOOT_WP                 173     /* R/W */
+#define EXT_CSD_ERASE_GROUP_DEF         175     /* R/W */
+#define EXT_CSD_PART_CONFIG             179     /* R/W */
+#define EXT_CSD_ERASED_MEM_CONT         181     /* RO */
+#define EXT_CSD_BUS_WIDTH               183     /* R/W */
+#define EXT_CSD_HS_TIMING               185     /* R/W */
+#define EXT_CSD_POWER_CLASS             187     /* R/W */
+#define EXT_CSD_REV                     192     /* RO */
+#define EXT_CSD_STRUCTURE               194     /* RO */
+#define EXT_CSD_CARD_TYPE               196     /* RO */
+#define EXT_CSD_OUT_OF_INTERRUPT_TIME   198     /* RO */
+#define EXT_CSD_PART_SWITCH_TIME        199     /* RO */
+#define EXT_CSD_PWR_CL_52_195           200     /* RO */
+#define EXT_CSD_PWR_CL_26_195           201     /* RO */
+#define EXT_CSD_PWR_CL_52_360           202     /* RO */
+#define EXT_CSD_PWR_CL_26_360           203     /* RO */
+#define EXT_CSD_SEC_CNT                 212     /* RO, 4 bytes */
+#define EXT_CSD_S_A_TIMEOUT             217     /* RO */
+#define EXT_CSD_REL_WR_SEC_C            222     /* RO */
+#define EXT_CSD_HC_WP_GRP_SIZE          221     /* RO */
+#define EXT_CSD_ERASE_TIMEOUT_MULT      223     /* RO */
+#define EXT_CSD_HC_ERASE_GRP_SIZE       224     /* RO */
+#define EXT_CSD_BOOT_MULT               226     /* RO */
+#define EXT_CSD_SEC_TRIM_MULT           229     /* RO */
+#define EXT_CSD_SEC_ERASE_MULT          230     /* RO */
+#define EXT_CSD_SEC_FEATURE_SUPPORT     231     /* RO */
+#define EXT_CSD_TRIM_MULT               232     /* RO */
+#define EXT_CSD_PWR_CL_200_195          236     /* RO */
+#define EXT_CSD_PWR_CL_200_360          237     /* RO */
+#define EXT_CSD_PWR_CL_DDR_52_195       238     /* RO */
+#define EXT_CSD_PWR_CL_DDR_52_360       239     /* RO */
+#define EXT_CSD_BKOPS_STATUS            246     /* RO */
+#define EXT_CSD_POWER_OFF_LONG_TIME     247     /* RO */
+#define EXT_CSD_GENERIC_CMD6_TIME       248     /* RO */
+#define EXT_CSD_CACHE_SIZE              249     /* RO, 4 bytes */
+#define EXT_CSD_TAG_UNIT_SIZE           498     /* RO */
+#define EXT_CSD_DATA_TAG_SUPPORT        499     /* RO */
+#define EXT_CSD_MAX_PACKED_WRITES       500     /* RO */
+#define EXT_CSD_MAX_PACKED_READS        501     /* RO */
+#define EXT_CSD_BKOPS_SUPPORT           502     /* RO */
+#define EXT_CSD_HPI_FEATURES            503     /* RO */
+
+/*
+ * EXT_CSD field definitions
+ */
+
+#define EXT_CSD_WR_REL_PARAM_EN         (1<<2)
+
+#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS    (0x40)
+#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS   (0x10)
+#define EXT_CSD_BOOT_WP_B_PERM_WP_EN    (0x04)
+#define EXT_CSD_BOOT_WP_B_PWR_WP_EN     (0x01)
+
+#define EXT_CSD_PART_CONFIG_ACC_MASK    (0x7)
+#define EXT_CSD_PART_CONFIG_ACC_BOOT0   (0x1)
+#define EXT_CSD_PART_CONFIG_ACC_RPMB    (0x3)
+#define EXT_CSD_PART_CONFIG_ACC_GP0     (0x4)
+
+#define EXT_CSD_PART_SUPPORT_PART_EN    (0x1)
+
+#define EXT_CSD_CMD_SET_NORMAL          (1<<0)
+#define EXT_CSD_CMD_SET_SECURE          (1<<1)
+#define EXT_CSD_CMD_SET_CPSECURE        (1<<2)
+
+#define EXT_CSD_CARD_TYPE_26    (1<<0)  /* Card can run at 26MHz */
+#define EXT_CSD_CARD_TYPE_52    (1<<1)  /* Card can run at 52MHz */
+#define EXT_CSD_CARD_TYPE_MASK  0x3F    /* Mask out reserved bits */
+#define EXT_CSD_CARD_TYPE_DDR_1_8V  (1<<2)   /* Card can run at 52MHz */
+                                              /* DDR mode @1.8V or 3V I/O */
+#define EXT_CSD_CARD_TYPE_DDR_1_2V  (1<<3)   /* Card can run at 52MHz */
+                                              /* DDR mode @1.2V I/O */
+#define EXT_CSD_CARD_TYPE_DDR_52       (EXT_CSD_CARD_TYPE_DDR_1_8V  \
+                                         | EXT_CSD_CARD_TYPE_DDR_1_2V)
+ #define EXT_CSD_CARD_TYPE_SDR_1_8V      (1<<4)  /* Card can run at 200MHz */
+#define EXT_CSD_CARD_TYPE_SDR_1_2V      (1<<5)  /* Card can run at 200MHz */
+                                                 /* SDR mode @1.2V I/O */
+
+#define EXT_CSD_BUS_WIDTH_1     0       /* Card is in 1 bit mode */
+#define EXT_CSD_BUS_WIDTH_4     1       /* Card is in 4 bit mode */
+#define EXT_CSD_BUS_WIDTH_8     2       /* Card is in 8 bit mode */
+#define EXT_CSD_DDR_BUS_WIDTH_4 5       /* Card is in 4 bit DDR mode */
+#define EXT_CSD_DDR_BUS_WIDTH_8 6       /* Card is in 8 bit DDR mode */
+
+#define EXT_CSD_SEC_ER_EN       BIT(0)
+#define EXT_CSD_SEC_BD_BLK_EN   BIT(2)
+#define EXT_CSD_SEC_GB_CL_EN    BIT(4)
+#define EXT_CSD_SEC_SANITIZE    BIT(6)  /* v4.5 only */
+
+#define EXT_CSD_RST_N_EN_MASK   0x3
+#define EXT_CSD_RST_N_ENABLED   1       /* RST_n is enabled on card */
+
+#define EXT_CSD_NO_POWER_NOTIFICATION   0
+#define EXT_CSD_POWER_ON                1
+#define EXT_CSD_POWER_OFF_SHORT         2
+#define EXT_CSD_POWER_OFF_LONG          3
+
+#define EXT_CSD_PWR_CL_8BIT_MASK        0xF0    /* 8 bit PWR CLS */
+#define EXT_CSD_PWR_CL_4BIT_MASK        0x0F    /* 8 bit PWR CLS */
+#define EXT_CSD_PWR_CL_8BIT_SHIFT       4
+#define EXT_CSD_PWR_CL_4BIT_SHIFT       0
+
+#define EXT_CSD_PACKED_EVENT_EN BIT(3)
+
+/*
+ * EXCEPTION_EVENT_STATUS field
+ */
+#define EXT_CSD_URGENT_BKOPS            BIT(0)
+#define EXT_CSD_DYNCAP_NEEDED           BIT(1)
+#define EXT_CSD_SYSPOOL_EXHAUSTED       BIT(2)
+#define EXT_CSD_PACKED_FAILURE          BIT(3)
+
+#define EXT_CSD_PACKED_GENERIC_ERROR    BIT(0)
+#define EXT_CSD_PACKED_INDEXED_ERROR    BIT(1)
+
+
+/*
+ * MMC_SWITCH access modes
+ *
+ * The SWITCH command response is of type R1b, therefore, the host should read the card status, using
+ * SEND_STATUS command, after the busy signal is de-asserted, to check the result of the SWITCH
+ * operation.
+ */
+#define MMC_SWITCH_MODE_CMD_SET         0x00    /* The command set is changed according to the Cmd Set field of the argument */
+#define MMC_SWITCH_MODE_SET_BITS        0x01    /* The bits in the pointed byte are set, according to the ‘1’ bits in the Value field. */
+#define MMC_SWITCH_MODE_CLEAR_BITS      0x02    /* The bits in the pointed byte are cleared, according to the ‘1’ bits in the Value field. */
+#define MMC_SWITCH_MODE_WRITE_BYTE      0x03    /* The Value field is written into the pointed byte. */
+
+
+unsigned int unstuffBits(unsigned int *resp,unsigned int start,unsigned int size)
+{
+	const int __size = size;
+	const unsigned int __mask = (__size < 32 ? 1 << __size : 0) - 1;
+	const int __off = 3 - ((start) / 32);
+	const int __shft = (start) & 31;
+	unsigned int __res;
+
+	__res = resp[__off] >> __shft;
+	if (__size + __shft > 32)
+	{
+		__res |= resp[__off-1] << ((32 - __shft) % 32);
+	}
+
+	return(__res & __mask);
+}
+
+/*
+ * EXT_CSD struct
+ */
+struct extCsd {
+	// [511:505] Reserved
+	char s_cmd_set;		 					// [504] Supported Command Sets
+	char hpi_features;						// [503] HPI features
+	char bkops_support; 					// [502] Background operations support
+	// [501:247] Reserved
+	char bkops_status;						// [246] Background operations status
+	unsigned int correctly_prg_sectors_num;	// [245:242] Number of correctly programmed sectors
+	char ini_timeout_ap;					// [241] 1st initialization time after partitioning
+	// [240] Reserved
+	char pwr_cl_ddr_52_360;					// [239] Power class for 52MHz, DDR at 3.6V
+	char pwr_cl_ddr_52_195;					// [238] Power class for 52MHz, DDR at 1.95V
+	// [237:236]
+	char min_perf_ddr_w_8_52;				// [235] Minimum Write Performance for 8bit at 52MHz in DDR mode
+	char min_perf_ddr_r_8_52;				// [234] Minimum Read Performance for 8bit at 52MHz in DDR mode
+	// [233]
+	char trim_mult;							// [232] TRIM Multiplier
+	char sec_feature_support;				// [231] Secure Feature support
+	char sec_erase_mult;					// [230] Secure Erase Multiplier
+	char sec_trim_mult;						// [229] Secure TRIM Multiplier
+	char boot_info;							// [228] Boot information
+	// [227] Reserved
+	char boot_size_multi;					// [226] Boot partition size
+	char acc_size;							// [225] Access size;
+	char hc_erase_grp_size;					// [224] High-capacity erase unit size
+	char erase_timeout_mult;				// [223] High-capacity erase timeout
+	char rel_wr_sec_c; 						// [222] Reliable write sector count
+	char hc_wp_grp_size;					// [221] High-capacity write protect group size
+	char s_c_vcc;							// [220] Sleep current (VCC)
+	char s_c_vccq;							// [219] Sleep current (VCCQ)
+	// [218] Reserved
+	char s_a_timeout;						// [217] Sleep/awake timeout
+	// [216] Reserved
+	unsigned int sec_count;					// [215:212] Sector Count
+	// [211] Reserved
+	char min_perf_w_8_52;					// [210] Minimum Write Performance for 8bit at 52MHz
+	char min_perf_r_8_52;					// [209] Minimum Read Performance for 8bit at 52MHz
+	char min_perf_w_8_26_4_52;				// [208] Minimum Write Performance for 8bit at 26MHz, for 4bit at 52MHz
+	char min_perf_r_8_26_4_52;				// [207] Minimum Read Performance for 8bit at 26MHz, for 4bit at 52MHz
+	char min_perf_w_4_26;					// [206] Minimum Write Performance for 4bit at 26MHz
+	char min_perf_r_4_26;					// [205] Minimum Read Performance for 4bit at 26MHz
+	// [211] Reserved
+	char pwr_cl_26_360;						// [203] Power class for 26MHz at 3.6V
+	char pwr_cl_52_360;						// [202] Power class for 52MHz at 3.6V
+	char pwr_cl_26_195;						// [201] Power class for 26MHz at 1.95V
+	char pwr_cl_52_195;						// [200] Power class for 52MHz at 1.95V
+	char partition_switch_time;				// [199] Partition switching timing
+	char out_of_interrupt_time;				// [198] Out-of-interrupt busy timing
+	// [197] Reserved
+	char card_type;							// [196] Card type
+	// [195] Reserved
+	char csd_structure;						// [194] CSD structure version
+	// [193] Reserved
+	char ext_csd_rev;						// [192] Extended CSD revision
+	char cmd_set;							// [191] Command set
+	// [190] Reserved
+	char cmd_set_rev;						// [189] Command set revision
+	// [188] Reserved
+	char power_class;						// [187] Power class
+	// [186] Reserved
+	char hs_timing;							// [185] High-speed interface timing
+	// [184] Reserved
+	char bus_width;							// [183] Bus width mode
+	// [182] Reserved
+	char erased_mem_cont;					// [181] Erased memory content
+	// [180] Reserved
+	char partition_config;					// [179] Partition configuration
+	char boot_config_prot;					// [178] Boot config protection
+	char boot_bus_width;					// [177] Boot bus width1
+	// [176] Reserved
+	char erase_group_def;					// [175] High-density erase group definition
+	// [174] Reserved;
+	char boot_wp;							// [173] Boot area write protection register
+	// [172] Reserved;
+	char user_wp;							// [171] User area write protection register
+	// [170] Reserved;
+	char fw_config;							// [169] FW configuration
+	char rpmb_size_mult;					// [168] RPMB Size
+	char wr_rel_set; 						// [167] Write reliability setting register
+	char wr_rel_param;						// [166] Write reliability parameter register
+	// [165] Reserved;
+	char bkops_start;						// [164] Manually start background operations
+	char bkops_en;							// [163] Enable background operations handshake
+	char rst_n_function;					// [162] H/W reset function
+	char hpi_mgmt;							// [161] HPI management
+	char partitioning_support;				// [160] Partitioning Support
+	unsigned char max_enh_size_mult; 		// [159:157] Max Enhanced Area Size
+	char partitions_attribute;				// [156] Partitions attribute
+	char partition_setting_completed; 		// [155] Paritioning Setting
+	unsigned int gp_size_mult[4];			// [154:143] General Purpose Partition Size
+	unsigned int enh_size_mult; 			// [142:140] Enhanced User Data Area Size
+	unsigned int enh_start_addr;			// [139:136] Enhanced User Data Start Address
+	// [135] Reserved;
+	char sec_bad_blk_mgmnt;			// [134] Bad Block Management mode
+	// [133:0] Reserved
+}extCsd;
+
+
+
+struct cardCSD
+{
+	char csd_structure;
+	char spec_vers;
+	char taac;
+	char nsac;
+	char tran_speed;
+	unsigned short ccc;
+	char read_bl_len;
+	char read_bl_partial;
+	char write_blk_misalign;
+	char read_blk_misalign;
+	char dsr_imp;
+	unsigned short c_size;
+	char vdd_r_curr_min;
+	char vdd_r_curr_max;
+	char vdd_w_curr_min;
+	char vdd_w_curr_max;
+	char c_size_mult;
+	char erase_grp_size;
+	char erase_grp_mult;
+	char wp_grp_size;
+	char wp_grp_enable;
+	char default_ecc;
+	char r2w_factor;
+	char write_bl_len;
+	char write_bl_partial;
+	char content_prot_app;
+	char file_format_grp;
+	char copy;
+	char perm_write_protect;
+	char tmp_write_protect;
+	char file_format;
+	char ecc;
+	char crc;
+} CSDInfo;
+
+
+struct cardCid {
+	char mid; 					/* Manufacturer ID */
+	char cbx;					/* Device/BGA */
+	char oid;					/* OEM/Application ID */
+	unsigned long int pnm;		/* Product name */
+	char prv;					/* Product revision  */
+	unsigned int psn;			/* Product serial number */
+	char mdt;					/* Manufacturing date */
+	char crc;					/* crc7 checksum */
+}cardCid;
 
-#define DATA_RESPONSE_WIDTH       (SOC_CACHELINE_SIZE)
 
 /* Cache size aligned data buffer (minimum of 64 bytes) for command response */
 #ifdef __TMS470__
@@ -64,6 +384,201 @@
 #error "Unsupported compiler\n\r"
 #endif
 
+int mmc_switch(mmcsdCtrlInfo *ctrl, char set, char index, char value);
+int mmc_send_status(mmcsdCtrlInfo *ctrl, unsigned int *status);
+unsigned int MMCSDCardTypeCheck(mmcsdCtrlInfo * ctrl);
+
+
+void decodeExtCsd(mmcsdCtrlInfo *ctrl, unsigned char *buffer)
+{
+	extCsd.s_cmd_set		 			= buffer[504];
+	extCsd.hpi_features					= buffer[503];// [503] HPI features
+	extCsd.bkops_support 				= buffer[502];// [502] Background operations support
+	// [501:247] Reserved
+	extCsd.bkops_status					= buffer[246]; // [246] Background operations status
+	extCsd.correctly_prg_sectors_num	=(buffer[245] << 24) | (buffer[244] << 16) | (buffer[243] << 8) | buffer[242];	// [245:242] Number of correctly programmed sectors
+	extCsd.ini_timeout_ap				= buffer[241]; // [241] 1st initialization time after partitioning
+	// [240] Reserved
+	extCsd.pwr_cl_ddr_52_360			= buffer[239];	// [239] Power class for 52MHz, DDR at 3.6V
+	extCsd.pwr_cl_ddr_52_195			= buffer[238];	// [238] Power class for 52MHz, DDR at 1.95V
+	// [237:236]
+	extCsd.min_perf_ddr_w_8_52			= buffer[235];// [235] Minimum Write Performance for 8bit at 52MHz in DDR mode
+	extCsd.min_perf_ddr_r_8_52			= buffer[234];// [234] Minimum Read Performance for 8bit at 52MHz in DDR mode
+	// [233]
+	extCsd.trim_mult					= buffer[232];	// [232] TRIM Multiplier
+	extCsd.sec_feature_support			= buffer[231];  // [231] Secure Feature support
+	extCsd.sec_erase_mult				= buffer[230];// [230] Secure Erase Multiplier
+	extCsd.sec_trim_mult				= buffer[229];	// [229] Secure TRIM Multiplier
+	extCsd.boot_info					= buffer[228];	// [228] Boot information
+	// [227] Reserved
+	extCsd.boot_size_multi				= buffer[226];// [226] Boot partition size
+	extCsd.acc_size						= buffer[225];// [225] Access size;
+	extCsd.hc_erase_grp_size			= buffer[224];	// [224] High-capacity erase unit size
+	extCsd.erase_timeout_mult			= buffer[223];// [223] High-capacity erase timeout
+	extCsd.rel_wr_sec_c 				= buffer[222];	// [222] Reliable write sector count
+	extCsd.hc_wp_grp_size				= buffer[221];// [221] High-capacity write protect group size
+	extCsd.s_c_vcc						= buffer[220];// [220] Sleep current (VCC)
+	extCsd.s_c_vccq						= buffer[219];// [219] Sleep current (VCCQ)
+	// [218] Reserved
+	extCsd.s_a_timeout					= buffer[217];// [217] Sleep/awake timeout
+	// [216] Reserved
+	extCsd.sec_count					= (buffer[215] << 24) | (buffer[124] << 16) | (buffer[213] << 8) | buffer[213];	// [215:212] Sector Count
+	// [211] Reserved
+	extCsd.min_perf_w_8_52				= buffer[210];// [210] Minimum Write Performance for 8bit at 52MHz
+	extCsd.min_perf_r_8_52				= buffer[209];// [209] Minimum Read Performance for 8bit at 52MHz
+	extCsd.min_perf_w_8_26_4_52			= buffer[208];// [208] Minimum Write Performance for 8bit at 26MHz, for 4bit at 52MHz
+	extCsd.min_perf_r_8_26_4_52			= buffer[207];// [207] Minimum Read Performance for 8bit at 26MHz, for 4bit at 52MHz
+	extCsd.min_perf_w_4_26				= buffer[206];// [206] Minimum Write Performance for 4bit at 26MHz
+	extCsd.min_perf_r_4_26				= buffer[205];// [205] Minimum Read Performance for 4bit at 26MHz
+	// [211] Reserved
+	extCsd.pwr_cl_26_360				= buffer[203];	// [203] Power class for 26MHz at 3.6V
+	extCsd.pwr_cl_52_360				= buffer[202];	// [202] Power class for 52MHz at 3.6V
+	extCsd.pwr_cl_26_195				= buffer[201];	// [201] Power class for 26MHz at 1.95V
+	extCsd.pwr_cl_52_195				= buffer[200];	// [200] Power class for 52MHz at 1.95V
+	extCsd.partition_switch_time		= buffer[199];	// [199] Partition switching timing
+	extCsd.out_of_interrupt_time		= buffer[198];	// [198] Out-of-interrupt busy timing
+	// [197] Reserved
+	extCsd.card_type					= buffer[196];	// [196] Card type
+	// [195] Reserved
+	extCsd.csd_structure				= buffer[194];	// [194] CSD structure version
+	// [193] Reserved
+	extCsd.ext_csd_rev					= buffer[192];// [192] Extended CSD revision
+	extCsd.cmd_set						= buffer[191];// [191] Command set
+	// [190] Reserved
+	extCsd.cmd_set_rev					= buffer[189];// [189] Command set revision
+	// [188] Reserved
+	extCsd.power_class					= buffer[187];// [187] Power class
+	// [186] Reserved
+	extCsd.hs_timing					= buffer[185];	// [185] High-speed interface timing
+	// [184] Reserved
+	extCsd.bus_width					= buffer[183];	// [183] Bus width mode
+	// [182] Reserved
+	extCsd.erased_mem_cont				= buffer[181];// [181] Erased memory content
+	// [180] Reserved
+	extCsd.partition_config				= buffer[179];// [179] Partition configuration
+	extCsd.boot_config_prot				= buffer[178];// [178] Boot config protection
+	extCsd.boot_bus_width				= buffer[177];// [177] Boot bus width1
+	// [176] Reserved
+	extCsd.erase_group_def				= buffer[175];// [175] High-density erase group definition
+	// [174] Reserved
+	extCsd.boot_wp						= buffer[173];// [173] Boot area write protection register
+	// [172] Reserved
+	extCsd.user_wp						= buffer[171];// [171] User area write protection register
+	// [170] Reserved
+	extCsd.fw_config					= buffer[169];	// [169] FW configuration
+	extCsd.rpmb_size_mult				= buffer[168];// [168] RPMB Size
+	extCsd.wr_rel_set 					= buffer[167];// [167] Write reliability setting register
+	extCsd.wr_rel_param					= buffer[166];// [166] Write reliability parameter register
+	// [165] Reserved
+	extCsd.bkops_start					= buffer[164];// [164] Manually start background operations
+	extCsd.bkops_en						= buffer[163];// [163] Enable background operations handshake
+	extCsd.rst_n_function				= buffer[162];// [162] H/W reset function
+	extCsd.hpi_mgmt						= buffer[161];// [161] HPI management
+	extCsd.partitioning_support			= buffer[160];// [160] Partitioning Support
+	extCsd.max_enh_size_mult 			= (buffer[159] << 16) | (buffer[158] << 8) | buffer[157]; // [159:157] Max Enhanced Area Size
+	extCsd.partitions_attribute			= buffer[156];// [156] Partitions attribute
+	extCsd.partition_setting_completed 	= buffer[155];// [155] Paritioning Setting
+	extCsd.gp_size_mult[0]				= (buffer[154] << 24) | (buffer[153] << 16) | (buffer[152] << 8) | buffer[151];// [154:143] General Purpose Partition Size
+	extCsd.gp_size_mult[1]				= (buffer[150] << 24) | (buffer[149] << 16) | (buffer[148] << 8) | buffer[147];// [154:143] General Purpose Partition Size
+	extCsd.gp_size_mult[2]				= (buffer[146] << 24) | (buffer[145] << 16) | (buffer[144] << 8) | buffer[143];// [154:143] General Purpose Partition Size
+	extCsd.enh_size_mult 				= (buffer[142] << 16) | (buffer[141] << 8) | buffer[140];// [142:140] Enhanced User Data Area Size
+	extCsd.enh_start_addr				= (buffer[139] << 24) | (buffer[138] << 16) | (buffer[137] << 8) | buffer[136];// [139:136] Enhanced User Data Start Address
+	// [135] Reserved;
+	extCsd.sec_bad_blk_mgmnt			= buffer[134];	// [134] Bad Block Management mode
+	// [133:0] Reserved
+
+	ctrl->card->cardType = extCsd.card_type;
+	ctrl->card->busWidth = extCsd.bus_width;
+}
+
+
+
+void GetCSDParameters(mmcsdCtrlInfo *ctrl)
+{
+	unsigned int blockNr = 0;
+	unsigned int mult = 0;
+
+	/* Describes the version of the CSD structure. */
+	CSDInfo.csd_structure = ((ctrl->card->raw_csd[3] & 0xC0000000) >> 30); // [127:126]
+	CSDInfo.spec_vers = ((ctrl->card->raw_csd[3] & 0x3C000000) >> 26); // [125:122] everything above 4 is reserved
+	// [121:120] reserved
+	CSDInfo.taac = ((ctrl->card->raw_csd[3] & 0x00FF0000) >> 16); // [119:112] Data read access-time 1
+	CSDInfo.nsac = ((ctrl->card->raw_csd[3] & 0x0000FF00) >> 8); // [111:104] Data read access-time 2 in CLK cycles (NSAC*100)
+	CSDInfo.tran_speed = (ctrl->card->raw_csd[3] & 0x000000FF); // [103:96] Max. bus clock frequency
+
+	CSDInfo.ccc = ((ctrl->card->raw_csd[2] & 0xFF000000) >> 20) | ((ctrl->card->raw_csd[2] & 0x00F00000) >> 20); // [95:84] Card command classes
+	CSDInfo.read_bl_len = ((ctrl->card->raw_csd[2] & 0x000F0000) >> 16); // [83:80] Max. read data block length
+	CSDInfo.read_bl_partial = ((ctrl->card->raw_csd[2] & 0x00008000) >> 15); // [79:79] Partial blocks for read allowed
+	CSDInfo.write_blk_misalign = ((ctrl->card->raw_csd[2] & 0x00004000) >> 14); // [78:78] WRITE_BLK_MISALIGN
+	CSDInfo.read_blk_misalign = ((ctrl->card->raw_csd[2] & 0x00002000) >> 13); // [77:77] READ_BLK_MISALIGN
+	CSDInfo.dsr_imp = ((ctrl->card->raw_csd[2] & 0x00001000) >> 12); // [76:76] DSR implemented
+	// [75:74] reserved
+	CSDInfo.c_size = ((ctrl->card->raw_csd[2] & 0x000003FF) << 2) | ((ctrl->card->raw_csd[1] & 0xC0000000) >> 30); // [73:62] Device size
+	CSDInfo.vdd_r_curr_min = ((ctrl->card->raw_csd[1] & 0x38000000) >> 27); // [61:59] Max. read current @ VDD min
+	CSDInfo.vdd_r_curr_max = ((ctrl->card->raw_csd[1] & 0x07000000) >> 24); // [58:56] Max. read current @ VDD max
+	CSDInfo.vdd_w_curr_min = ((ctrl->card->raw_csd[1] & 0x00E00000) >> 21); // [55:53] Max. write current @ VDD min
+	CSDInfo.vdd_w_curr_max = ((ctrl->card->raw_csd[1] & 0x001C0000) >> 18); // [52:50] Max. write current @ VDD max
+	CSDInfo.c_size_mult = ((ctrl->card->raw_csd[1] & 0x00038000) >> 15); // [49:47] Device size multiplier
+	CSDInfo.erase_grp_size = ((ctrl->card->raw_csd[1] & 0x00007C00) >> 10); // [46:42] Erase group size
+	CSDInfo.erase_grp_mult = ((ctrl->card->raw_csd[1] & 0x000003E0) >> 5); // [41:37] Erase group size multiplier
+	CSDInfo.wp_grp_size = (ctrl->card->raw_csd[1] & 0x0000001F); // [36:32] Write protect group size
+	CSDInfo.wp_grp_enable = ((ctrl->card->raw_csd[0] & 0x80000000) >> 31); // [31:31] WP_GRP_ENABLE
+	CSDInfo.default_ecc = ((ctrl->card->raw_csd[0] & 0x60000000) >> 29); // [30:29] Manufacturer default ECC
+	CSDInfo.r2w_factor = ((ctrl->card->raw_csd[0] & 0x1C000000) >> 26); // [28:26] Write speed factor
+	CSDInfo.write_bl_len = ((ctrl->card->raw_csd[0] & 0x03C00000) >> 22); // [25:22] Max. write data block length
+	CSDInfo.write_bl_partial = ((ctrl->card->raw_csd[0] & 0x00200000) >> 21); // [21:21] Partial blocks for write allowed
+	// [20:17]
+	CSDInfo.content_prot_app = ((ctrl->card->raw_csd[0] & 0x00010000) >> 16); // [16:16] Content protection application
+	CSDInfo.file_format_grp = ((ctrl->card->raw_csd[0] & 0x00008000) >> 13); // [15:15] File format group
+	CSDInfo.copy = ((ctrl->card->raw_csd[0] & 0x00004000) >> 12); // [14:14] Copy flag (OTP)
+	CSDInfo.perm_write_protect = ((ctrl->card->raw_csd[0] & 0x00002000) >> 11); // [13:13] Permanent write protection
+	CSDInfo.tmp_write_protect = ((ctrl->card->raw_csd[0] & 0x00001000) >> 10); // [12:12] Temporary write protection
+	CSDInfo.file_format = ((ctrl->card->raw_csd[0] & 0x00000C00) >> 10); // [11:10] File format
+	CSDInfo.ecc = ((ctrl->card->raw_csd[0] & 0x00000300) >> 8); // [9:8] ECC code
+	CSDInfo.crc = (ctrl->card->raw_csd[0] & 0x000000FE); // [7:1] CRC
+	// [0:0] Not used, always’1’
+
+
+	mult = 2^(CSDInfo.c_size + 2);
+	blockNr = (CSDInfo.c_size + 1) * mult;
+	ctrl->card->size = blockNr * mult;
+
+
+	//ctrl->card->blkLen = 1 << (CSDInfo.read_bl_len);
+	ctrl->card->blkLen = 1 << (CSDInfo.read_bl_len - 1); // Set it to 512 /////////////////////////////////////////////////////////
+
+	ctrl->card->nBlks = ctrl->card->size/ctrl->card->blkLen;
+
+	ctrl->card->tranSpeed = CSDInfo.tran_speed ;
+}
+
+
+void getCID(mmcsdCtrlInfo *ctrl)
+{
+	unsigned int temp[4];
+	int i;
+
+	// UNSTUFF_BITS() read in a reverse order so use a temp buffer
+	for(i=0; i<4; i++)
+	{
+		temp[3-i] = ctrl->card->raw_cid[i];
+	}
+
+	unsigned int *resp = temp;
+
+	cardCid.mid	= (char)unstuffBits(resp,120,8);
+	cardCid.cbx	= (char)unstuffBits(resp,112,2);
+	cardCid.oid	= (char)unstuffBits(resp,102,8);
+	cardCid.pnm	= unstuffBits(resp,56,48); // This value is not correct!
+	cardCid.prv	= (char)unstuffBits(resp,48,8);
+	cardCid.psn	= unstuffBits(resp,16,32);
+	cardCid.mdt	= (char)unstuffBits(resp,8,8);
+	cardCid.crc	= (char)unstuffBits(resp,1,7);
+}
+
+
+
+
 /**
  * \brief   This function sends the command to MMCSD.
  *
@@ -117,11 +632,12 @@
  *
  * \param    mmcsdCtrlInfo It holds the mmcsd control information.
  *
- * \param   buswidth   SD/MMC bus width.\n
+ * \param   buswidth   SD/MMC bus width.
  * 
- *  buswidth can take the values.\n 
- *     HS_MMCSD_BUS_WIDTH_4BIT.\n
- *     HS_MMCSD_BUS_WIDTH_1BIT.\n
+ *  buswidth can take the values.
+ *     HS_MMCSD_BUS_WIDTH_8BIT.
+ *     HS_MMCSD_BUS_WIDTH_4BIT.
+ *     HS_MMCSD_BUS_WIDTH_1BIT.
  *
  * \return  None.
  *
@@ -144,6 +660,15 @@
         }
     }
 
+    else if(ctrl->busWidth & SD_BUS_WIDTH_8BIT)
+    {
+    	if (card->busWidth & SD_BUS_WIDTH_8BIT)
+		{
+			capp.arg = SD_BUS_WIDTH_8BIT;
+		}
+    }
+
+
     capp.arg = capp.arg >> 1;
 
     status = MMCSDAppCmdSend(ctrl, &capp);
@@ -154,6 +679,10 @@
         {
             ctrl->busWidthConfig(ctrl, SD_BUS_WIDTH_1BIT);
         }
+        else if (capp.arg == SD_BUS_WIDTH_8BIT)
+        {
+        	ctrl->busWidthConfig(ctrl, SD_BUS_WIDTH_8BIT);
+        }
         else
         {
             ctrl->busWidthConfig(ctrl, SD_BUS_WIDTH_4BIT);
@@ -178,13 +707,20 @@
     unsigned int cmdStatus = 0;
     mmcsdCmd cmd;
 
+
+    /* Returns 1 for a SD card, 0 for a non-SD card */
+	status = MMCSDCardTypeCheck(ctrl);
+
+	if (status == 1)
+	/* SD Card */
+	{
     ctrl->xferSetup(ctrl, 1, dataBuffer, 64, 1);
 
     cmd.idx = SD_CMD(6);
     cmd.arg = ((SD_SWITCH_MODE & SD_CMD6_GRP1_SEL) | (SD_CMD6_GRP1_HS));
     cmd.flags = SD_CMDRSP_READ | SD_CMDRSP_DATA;
     cmd.nblks = 1;
-    cmd.data = (signed char*)dataBuffer;
+		cmd.data = (unsigned char*)dataBuffer;
 
     cmdStatus = MMCSDCmdSend(ctrl, &cmd);
 
@@ -227,6 +763,67 @@
     }
 
     return 1;
+	}
+	else
+	{
+		/* eMMC */
+
+		ctrl->xferSetup(ctrl, 1, dataBuffer, 512, 1);
+
+		cmd.idx = SD_CMD(8);
+		cmd.flags = SD_CMDRSP_DATA | SD_CMDRSP_READ;
+		cmd.arg = 0;
+		cmd.nblks = 1;
+		cmd.data = (unsigned char*)dataBuffer;
+
+		status = MMCSDCmdSend(ctrl,&cmd);
+		if (status == 0)
+		{
+			UARTPuts("error CMD8 \n", -1);
+			return 0;
+		}
+
+
+		status = ctrl->xferStatusGet(ctrl);
+
+		if (status == 0)
+		{
+			UARTPuts("error xferStatusGet \n", -1);
+			return 0;
+		}
+
+		/* Invalidate the data cache. */
+		CacheDataInvalidateBuff((unsigned int)dataBuffer, 512);
+
+		speed = card->tranSpeed;
+
+		// If high speed is enabled
+		if ((dataBuffer[185]) == SD_CMD6_GRP1_HS)
+		{
+			card->tranSpeed = SD_TRANSPEED_50MBPS;
+			status = ctrl->busFreqConfig(ctrl, 52000000);
+			ctrl->opClk = 52000000;
+		}
+
+		else if(card->tranSpeed == SD_TRANSPEED_25MBPS)
+		{
+			status = ctrl->busFreqConfig(ctrl, 26000000);
+			ctrl->opClk = 26000000;
+		}
+
+		else
+		{
+			// unknown bus speed
+			return 0;
+		}
+
+		if (status != 0)
+		{
+			return 0;
+		}
+
+		return 1;
+	}
 }
 
 /**
@@ -244,7 +841,7 @@
 
     cmd.idx = SD_CMD(0);
     cmd.flags = SD_CMDRSP_NONE;
-    cmd.arg = 0;
+    cmd.arg = 0x0;
 
     status = MMCSDCmdSend(ctrl, &cmd);
 
@@ -541,7 +1138,7 @@
         cmd.flags = SD_CMDRSP_READ | SD_CMDRSP_DATA;
         cmd.arg = card->rca << 16;
         cmd.nblks = 1;
-        cmd.data = (signed char*)dataBuffer;
+        cmd.data = (unsigned char*)dataBuffer;
 
         status = MMCSDCmdSend(ctrl,&cmd);
         if (status == 0)
@@ -568,10 +1165,208 @@
         card->busWidth = SD_CARD_BUSWIDTH(card);
     }
     else
+    /* onboard mmc */
+    {
+    	ctrl->card->cardType = MMCSD_CARD_MMC;
+
+    	/* eMMC reconfigure the controller */
+    	ctrl->busWidthConfig(ctrl, HS_MMCSD_BUS_WIDTH_1BIT);
+    	ctrl->card->busWidth = 1;
+
+
+
+
+		/*
+		 * After receiving Command GO_IDLE_STATE (CMD0 with argument of 0x00000000),
+		 * the cards go to Idle State.
+		 */
+		status = MMCSDCardReset(ctrl);
+
+		if (status == 0)
+		{
+			UARTPuts("error GO_IDLE_STATE \n", -1);
+			return 0;
+		}
+
+		/*
+		 * The SEND_OP_COND (CMD1) command is designed to provide MultiMediaCard hosts with a
+		 * mechanism to identify and reject cards which do not match the VDD range desired by the host. This is
+		 * accomplished by the host sending the required VDD voltage window as the operand of this command
+		 *
+		 * For e•MMC devices, the voltage range in CMD1 is no longer valid. Regardless of the voltage range
+		 * indicated by the host, the e•MMC devices shall respond with a fixed pattern of either 0x00FF 8080
+		 * (capacity less than or equal to 2GB) or 0x40FF 8080 (capacity greater than 2GB) if device is busy, and
+		 * they shall not move into Inactive state.
+		 *
+		 * For e•MMC devices, the host shall still send the correct Access mode in CMD1 argument.
+		 */
+
+
+
+		/* loop until the card is not busy */
+		do {
+
+			cmd.idx = SD_CMD(1);
+			cmd.arg = 0x40FF8000;
+			cmd.flags = SD_CMDRSP_R3;
+
+			status = MMCSDCmdSend(ctrl, &cmd);
+
+			if (status == 0)
+			{
+				UARTPuts("error CMD1 \n", -1);
+				return 0;
+			}
+			int delay = 0xFF;
+			while(delay--); // wait for it to response
+
+		} while (!(cmd.rsp[0] & ((unsigned int)BIT(31))) && retry--);
+
+		if(retry == 0)
+		{
+			UARTPuts("Timeout\n", -1);
+			return 0;
+		}
+
+		card->ocr = cmd.rsp[0];
+		/* The extra bit indicates if we support high capacity */
+		card->highCap = (card->ocr & SD_OCR_HIGH_CAPACITY) ? 1 : 0;
+
+
+		/*
+		 * Fetch CID from card.
+		 * ALL_SEND_CID (CMD2), asking all cards for their unique card identification (CID) number
+		 */
+
+		/* Send CMD2, to get the card identification register */
+		cmd.idx = SD_CMD(2);
+		cmd.flags = SD_CMDRSP_R2;
+		cmd.arg = 0;
+
+		status = MMCSDCmdSend(ctrl,&cmd);
+
+		if (status == 0)
     {
+			UARTPuts("error CMD2 \n", -1);
         return 0;
     }
 
+
+		/*
+		 * Save response in the allocate card structure.
+		 */
+		memcpy(card->raw_cid, cmd.rsp, 16);
+
+
+		/* save the raw data in a structure */
+		getCID(ctrl);
+
+		/* Send CMD3, to set the card relative address
+		 *
+		 * The writable 16-bit relative card address (RCA) register carries the card address assigned by the host during
+		 * the card identification. This address is used for the addressed host-card communication after the card
+		 * identification procedure. The default value of the RCA register is 0x0001. The value 0x0000 is reserved to
+		 * set all cards into the Stand-by State with CMD7.
+		 *
+		 */
+
+		/* Set the default value of the RCA register */
+		card->rca = 1;
+
+		cmd.idx = SD_CMD(3);
+		cmd.flags = SD_CMDRSP_R1;
+		cmd.arg = card->rca << 16;
+
+		status = MMCSDCmdSend(ctrl,&cmd);
+
+		if (status == 0)
+		{
+			UARTPuts("error CMD3 \n", -1);
+			return 0;
+		}
+
+		/* Send CMD9, to get the card specific data */
+		cmd.idx = SD_CMD(9);
+		cmd.flags = SD_CMDRSP_R2;
+		cmd.arg = card->rca << 16;
+
+		status = MMCSDCmdSend(ctrl,&cmd);
+
+		memcpy(card->raw_csd, cmd.rsp, 16);
+
+		if (status == 0)
+		{
+			UARTPuts("error CMD9 \n", -1);
+			return 0;
+		}
+
+		GetCSDParameters(ctrl);
+
+
+		/*
+		 * Select card, as all following commands rely on that.
+		 */
+		cmd.idx = SD_CMD(7);
+		cmd.flags = SD_CMDRSP_R1;
+		cmd.arg = card->rca << 16;
+
+		status = MMCSDCmdSend(ctrl,&cmd);
+
+		if (status == 0)
+		{
+			UARTPuts("error CMD7 \n", -1);
+			return 0;
+		}
+
+		/*
+		 * Now that the card is selected we can read the extended CSD.
+		 */
+
+		//    xferSetup(mmcsdCtrlInfo, rwFlag,*ptr,blkSize,nBlks)
+		ctrl->xferSetup(ctrl, 1, dataBuffer, 512, 1);
+
+		cmd.idx = SD_CMD(8);
+		cmd.flags = SD_CMDRSP_DATA | SD_CMDRSP_READ;
+		cmd.arg = 0;
+		cmd.nblks = 1;
+		cmd.data = (unsigned char*)dataBuffer;
+
+		status = MMCSDCmdSend(ctrl,&cmd);
+		if (status == 0)
+		{
+			UARTPuts("error CMD8 \n", -1);
+			return 0;
+		}
+
+
+		status = ctrl->xferStatusGet(ctrl);
+
+		if (status == 0)
+		{
+			UARTPuts("error xferStatusGet \n", -1);
+			return 0;
+		}
+
+		/* Invalidate the data cache. */
+		CacheDataInvalidateBuff((unsigned int)dataBuffer, 512);
+
+		decodeExtCsd(ctrl,dataBuffer);
+
+		/* enable High speed */
+		if(mmc_switch(ctrl,MMC_SWITCH_MODE_WRITE_BYTE,EXT_CSD_HS_TIMING,0x1))
+		{
+			ctrl->highspeed = 1;
+		}
+
+		/* Set the bus width to 8 */
+		if(mmc_switch(ctrl,MMC_SWITCH_MODE_WRITE_BYTE,EXT_CSD_BUS_WIDTH,EXT_CSD_BUS_WIDTH_8))
+		{
+			card->busWidth = 8;
+			ctrl->busWidthConfig(ctrl, HS_MMCSD_BUS_WIDTH_8BIT);
+		}
+
+    }
+
     return 1;
 }
 
@@ -732,3 +1527,85 @@
 
     return 1;
 }
+
+
+/**
+ *    mmc_switch - modify EXT_CSD register
+ *    card: the MMC card associated with the data transfer
+ *    set: cmd set values
+ *    index: EXT_CSD register index
+ *    value: value to program into EXT_CSD register
+ *
+ *
+ *    Modifies the EXT_CSD register for selected card.
+ */
+int mmc_switch(mmcsdCtrlInfo *ctrl, char set, char index, char value)
+{
+	mmcsdCmd cmd;
+	unsigned int status = 0;
+	int err;
+    cmd.idx = SD_CMD(6);
+    cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+          (index << 16) |
+          (value << 8) |
+          set;
+    cmd.flags = SD_CMDRSP_R1b;
+
+    err = MMCSDCmdSend(ctrl,&cmd);
+
+	if (err == 0)
+	{
+		UARTPuts("error CMD6 \n", -1);
+		return 0;
+	}
+
+    /* Must check status to be sure of no errors */
+    do
+    {
+        err = mmc_send_status(ctrl, &status);
+        if (err)
+        {
+        	UARTPuts("error status failed\n", -1);
+            //return 0;
+        }
+
+        if(status & (BIT(7)))
+        {
+        	// switch error
+        	UARTPuts("switch error\n", -1);
+        	return 0;
+        }
+
+        if(status & (BIT(22)))
+	   {
+        	// Illegal command
+        	UARTPuts("Illegal command\n", -1);
+        	return 0;
+	   }
+
+    } while (!(status & BIT(8)) & (!err)); // run while the card is not ready
+
+
+    return 1;
+}
+
+
+int mmc_send_status(mmcsdCtrlInfo *ctrl, unsigned int *status)
+{
+    int err;
+    mmcsdCmd cmd;
+
+    cmd.idx = SD_CMD(13);
+    cmd.arg = ctrl->card->rca << 16;
+    cmd.flags = SD_CMDRSP_R1;
+
+    err = MMCSDCmdSend(ctrl, &cmd);
+	if (err == 0)
+	{
+		return 0;
+	}
+
+    *status = cmd.rsp[0];
+
+    return 1;
+}
