1 // ==========================================================================
6 // MMC card driver for MXC platform
8 // ==========================================================================
9 //####ECOSGPLCOPYRIGHTBEGIN####
10 // -------------------------------------------
11 // This file is part of eCos, the Embedded Configurable Operating System.
12 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //==========================================================================
42 //#####DESCRIPTIONBEGIN####
44 // Author(s): Ivan Xu <yu.xu@freescale.com>
45 // Contributors: Ivan Xu <yu.xu@freescale.com>
46 // Date: 2008-06-13 Initial version
49 // Support SD/MMC cards based on SDHC controller.
50 // only base functionality is implemented: Card init, read, write and erase.
51 // Write protection are not supported so far.
53 //####DESCRIPTIONEND####
55 //==========================================================================
57 #include <cyg/io/card_mx32.h>
58 #include <cyg/hal/hal_io.h>
62 //#define diag_printf1 diag_printf
63 #define diag_printf1(fmt,args...)
65 volatile psdhc_t pSDHC;
66 card_mode_t Card_Mode;
67 cyg_uint32 HighCapacityCard = 0;
68 cyg_uint32 card_address;
69 card_type Card_type; /* Card Type*/
71 CARD_SPECIFIC_DATA csd; /* Global variable for Card Specific Data */
72 cyg_uint32 CCC = 0; /* Card Command Class */
74 static struct csd_v1_0 g_csd_val;
76 static void configure_cmd (command_t *cmd,cyg_uint32 index, cyg_uint32 argument,
77 cyg_uint32 transfer,cyg_uint32 response_format, cyg_uint32 data_enable,
78 cyg_uint32 bus_width )
80 /* Configure Command index */
83 /* Configure Command argument */
85 /* workaround for CMD0, send 80 clock cycles before CMD0 */
88 cmd->data_control = (((transfer) << SDHC_CMD_WRITE_READ_SHIFT) |
89 ((response_format) << SDHC_CMD_FROMAT_OF_RESP_SHIFT) |
90 ((data_enable) << SDHC_CMD_DATA_ENABLE_SHIFT) |
91 ((bus_width) << SDHC_CMD_BUS_WIDTH_SHIFT)) |
92 (0x1 << SDHC_CMD_INIT_SHIFT );
94 cmd->data_control = (((transfer) << SDHC_CMD_WRITE_READ_SHIFT) |
95 ((response_format) << SDHC_CMD_FROMAT_OF_RESP_SHIFT) |
96 ((data_enable) << SDHC_CMD_DATA_ENABLE_SHIFT) |
97 ((bus_width) << SDHC_CMD_BUS_WIDTH_SHIFT));
101 static void stop_clk(void)
104 // pSDHC->sdhc_clk = SDHC_CLK_STOP;
106 /* Wait till the clock has stopped */
107 // while((pSDHC->sdhc_status & SDHC_STATUS_CARD_BUS_CLK_RUN_MSK));
111 static void start_clk(void)
113 /* Start the clock */
114 pSDHC->sdhc_clk = SDHC_CLK_START;
116 /* Wait till the clock has started */
117 while(!(pSDHC->sdhc_status & SDHC_STATUS_CARD_BUS_CLK_RUN_MSK));
121 static void configure_clk(frequency_mode_t mode)
123 if(mode == iden_mode)
126 pSDHC->sdhc_clk_rate = 0x207;
128 else if(mode == trans_mode)
131 pSDHC->sdhc_clk_rate = 0x3;
134 diag_printf1("pSDHC->sdhc_clk_rate=0x%x\n", pSDHC->sdhc_clk_rate);
137 static void read_response(cyg_uint32 response_mode, response_t*response)
144 if(response_mode != 0)
146 if((response_mode == RESPONSE_48_CRC) || (response_mode == RESPONSE_48_WITHOUT_CRC))
148 resp1 = readl(0x50004000 + 0x34) & 0xffff;
149 resp2 = readl(0x50004000 + 0x34) & 0xffff;
150 resp3 = readl(0x50004000 + 0x34) & 0xffff;
152 response->rsp0 = (resp1 << 24) | (resp2 << 8) | (resp3 >> 8);
154 else if(response_mode == RESPONSE_136)
156 resp1 = pSDHC->sdhc_res_fifo & 0xffff;
157 resp2 = pSDHC->sdhc_res_fifo & 0xffff;
158 response->rsp3 = (resp1 << 16) | resp2;
159 resp1 = pSDHC->sdhc_res_fifo & 0xffff;
160 resp2 = pSDHC->sdhc_res_fifo & 0xffff;
161 response->rsp2 = (resp1 << 16) | resp2;
163 resp1 = pSDHC->sdhc_res_fifo & 0xffff;
164 resp2 = pSDHC->sdhc_res_fifo & 0xffff;
165 response->rsp1 = (resp1 << 16) | resp2;
167 resp1 = pSDHC->sdhc_res_fifo & 0xffff;
168 resp2= pSDHC->sdhc_res_fifo & 0xffff;
169 response->rsp0 = (resp1 << 16) | resp2;
174 /* Clear w1c bits from STATUS register */
175 pSDHC->sdhc_status |= SDHC_STATUS_CLEAR;
181 static cyg_uint32 check_response(void)
183 cyg_uint32 status = PASS;
185 if((pSDHC->sdhc_status & SDHC_STATUS_END_CMD_RESP_MSK) &&
186 !(pSDHC->sdhc_status & SDHC_STATUS_TIME_OUT_RESP_MSK) &&
187 !(pSDHC->sdhc_status & SDHC_STATUS_RESP_CRC_ERR_MSK))
194 diag_printf("response status: %x Fail!\n", pSDHC->sdhc_status);
199 static cyg_uint32 send_cmd_and_wait_resp(command_t *cmd)
201 /* Clear Interrupt status Register and enable int*/
202 pSDHC->sdhc_status = 0xFFFFFFFF;
203 pSDHC->sdhc_int_cntr = SDHC_INT;
205 /* Write command index */
206 pSDHC->sdhc_cmd = cmd->index;
208 /* Write command arg */
209 pSDHC->sdhc_arg = cmd->arg;
211 /* Write command data control */
212 pSDHC->sdhc_dat_cont = cmd->data_control;
217 /* Wait for the response of command end */
218 while(!(pSDHC->sdhc_status & SDHC_STATUS_END_CMD_RESP_MSK) );
220 /* Mask all interrupts */
221 pSDHC->sdhc_int_cntr = 0;
223 /* Check if an error occured */
224 return check_response();
227 static cyg_uint32 card_get_csd (void)
231 cyg_uint32 status = FAIL;
232 //cyg_uint32 card_address = (Card_rca << RCA_SHIFT);
234 /* Configure CMD9 for MMC/SD card */
235 /* 16bit card address is expected as Argument */
236 configure_cmd(&cmd,CMD9,card_address,READ,RESPONSE_136, DISABLE, ONE);
238 /* Send Command CMD9 to Extrace CSD register contents */
239 if(send_cmd_and_wait_resp(&cmd) != FAIL)
241 /* Read Command response */
242 read_response (RESPONSE_136, &response);
243 /* Assign Response to CSD Strcuture */
244 csd.csd0 = response.rsp0;
245 csd.csd1 = response.rsp1;
246 csd.csd2 = response.rsp2;
247 csd.csd3 = response.rsp3;
248 diag_printf1("CSD:%x:%x:%x:%x\n", csd.csd0, csd.csd1, csd.csd2, csd.csd3);
251 memcpy(&g_csd_val, &csd, sizeof(struct csd_v1_0));
252 diag_printf1("g_csd_val.c_size_mult=0x%x\n", g_csd_val.c_size_mult);
253 diag_printf1("g_csd_val addr=%p\n", &g_csd_val);
259 static cyg_uint32 csd_get_value(CARD_SPECIFIC_DATA * pcsd, cyg_uint32 start_bit, cyg_uint32 end_bit)
262 if (start_bit == 84) {
263 value = g_csd_val.ccc;
264 } else if (start_bit == 62) {
265 value = (g_csd_val.c_size_up << 2) | g_csd_val.c_size_lo;
266 } else if (start_bit == 47) {
267 value = g_csd_val.c_size_mult;
268 } else if (start_bit == 80) {
269 value = g_csd_val.read_bl_len;
270 } else if (start_bit == 48) {
271 struct csd_v2_0 *ptr = (struct csd_v2_0 *) &g_csd_val;
272 value = (ptr->c_size_up << 16) | ptr->c_size_lo;
274 diag_printf1("start_bit=%d is not supported\n", start_bit);
277 diag_printf1("start_bit=%d, end_bit=%d, value=0x%x\n", start_bit, end_bit, value);
281 static cyg_uint32 mmc_init(void)
283 cyg_uint32 status = FAIL;
287 cyg_uint32 card_status = 0;
290 card_address = 0x1<<16;
292 /* Configure CMD2 for card */
293 configure_cmd(&cmd,CMD2,NO_ARG,READ,RESPONSE_136,DISABLE,ONE);
295 /* Send CMD2 to card to determine CID contents */
296 if(send_cmd_and_wait_resp(&cmd) == FAIL)
303 /* Read Command response */
304 read_response(RESPONSE_136, &resp);
305 /* Assign CID values to mmc_cid structures */
306 card_id.cid0 = resp.rsp0;
307 card_id.cid1 = resp.rsp1;
308 card_id.cid2 = resp.rsp2;
309 card_id.cid3 = resp.rsp3;
315 /* Configure CMD3 for MMC card */
316 configure_cmd(&cmd,CMD3,card_address,READ,RESPONSE_48_CRC, DISABLE, ONE);
318 /* Assigns relative address to the card */
319 if(send_cmd_and_wait_resp(&cmd) == FAIL)
326 /* Read Command response */
327 read_response(RESPONSE_48_CRC, &resp);
328 card_status = resp.rsp0;
329 card_status = (((cyg_uint32) (card_status & CARD_STATE)) >> CARD_STATE_SHIFT);
330 if(card_status == IDENT)
343 configure_clk(trans_mode);
345 /*Send MMC to Transfer State */
346 /* Configure CMD7 for MMC card */
347 configure_cmd(&cmd,CMD7,card_address,READ,RESPONSE_48_CRC, DISABLE,ONE);
349 if(send_cmd_and_wait_resp(&cmd) == FAIL)
356 /* Configure CMD13 to read status of the card becuase CMD7 has R1b response */
357 configure_cmd(&cmd,CMD13,card_address,READ,RESPONSE_48_CRC,DISABLE,ONE);
358 if(send_cmd_and_wait_resp(&cmd) == FAIL)
365 /* Read Command response */
366 read_response (RESPONSE_48_CRC, &resp);
367 card_status = resp.rsp0;
368 card_status = (((cyg_uint32) (card_status & CARD_STATE)) >> CARD_STATE_SHIFT);
370 if(card_status == TRAN)
384 static cyg_uint32 check_sd(void)
387 //command_response_t response;
389 cyg_uint32 default_rca = 0;
390 cyg_uint32 ocr_value=0;
391 cyg_uint32 status = FAIL;
394 configure_cmd(&cmd,CMD8,0x1AA,READ,RESPONSE_48_CRC, DISABLE, ONE);
395 send_cmd_and_wait_resp(&cmd);
397 while((count < 3000) && (status != PASS))
399 /* Configure CMD55 for SD card */
400 configure_cmd(&cmd,CMD55,default_rca,READ,RESPONSE_48_CRC, DISABLE, ONE);
402 /* Send CMD55 to SD Memory card*/
403 if(send_cmd_and_wait_resp(&cmd) == FAIL)
407 diag_printf1("CMD55 FAIL!\n");
413 ocr_value = ((cyg_uint32)(OCR_VALUE) & 0xFFFFFFFF);
414 /* Configure ACMD41 for SD card */
415 configure_cmd(&cmd,ACMD41,ocr_value,READ,RESPONSE_48_WITHOUT_CRC,DISABLE, ONE);
416 /* SEND ACMD41 to SD Memory card to determine OCR value */
417 if(send_cmd_and_wait_resp(&cmd) == FAIL)
420 diag_printf1("ACMD41 FAIL!\n");
425 /* Read Response from CMDRSP0 Register */
426 read_response(RESPONSE_48_WITHOUT_CRC, &resp);
427 ocr_value = resp.rsp0;
428 diag_printf1("SD: response ocr value: 0x%x\n", ocr_value);
429 /* Check if volatge lies in range or not*/
430 if((ocr_value & OCR_VALUE_MASK) == OCR_VALUE_MASK)
432 diag_printf1("response.cmd_rsp0: 0x%x\n", ocr_value);
433 /* Check if card busy bit is cleared or not */
434 if(ocr_value & CARD_BUSY)
441 diag_printf1("SD: Busy! \n");
447 diag_printf("SD: response ocr value: 0x%x FAIL!\n", ocr_value);
456 static cyg_uint32 sd_init(cyg_uint32 bus_width)
458 cyg_uint32 status = FAIL;
461 cyg_uint32 card_status = 0;
462 cyg_uint32 read_resp = 0;
467 /* Configure CMD2 for card */
468 configure_cmd(&cmd,CMD2,NO_ARG,READ,RESPONSE_136,DISABLE,ONE);
470 /* Send CMD2 to card to determine CID contents */
471 if(send_cmd_and_wait_resp(&cmd) == FAIL)
478 /* Read Command response */
479 read_response(RESPONSE_136, &resp);
480 /* Assign CID values to mmc_cid structures */
481 card_id.cid0 = resp.rsp0;
482 card_id.cid1 = resp.rsp1;
483 card_id.cid2 = resp.rsp2;
484 card_id.cid3 = resp.rsp3;
489 /* get rca of card */
490 /* Configure CMD3 for card */
491 configure_cmd(&cmd,CMD3,NO_ARG,READ,RESPONSE_48_CRC, DISABLE, ONE);
493 /* Assigns relative address to the card */
494 if(send_cmd_and_wait_resp(&cmd) == FAIL)
501 /* Read Command response */
502 read_response(RESPONSE_48_CRC, &resp);
503 card_status = resp.rsp0;
504 card_address = ((cyg_uint32) (card_status & (0xffffff00)));
505 card_status = (((cyg_uint32) (card_status & CARD_STATE)) >> CARD_STATE_SHIFT);
506 if(card_status == IDENT)
518 configure_clk(trans_mode);
520 /*Send card to Transfer State */
521 /* Configure CMD7 for card */
522 configure_cmd(&cmd,CMD7,card_address,READ,RESPONSE_48_CRC, DISABLE,ONE);
523 if(send_cmd_and_wait_resp(&cmd) == FAIL)
530 /* Configure CMD13 to read status of the card becuase CMD7 has R1b response */
531 configure_cmd(&cmd,CMD13,card_address,READ,RESPONSE_48_CRC,
534 if(send_cmd_and_wait_resp(&cmd) == FAIL)
541 /* Read Command response */
542 read_response (RESPONSE_48_CRC, &resp);
543 card_status = resp.rsp0;
544 card_status = (((cyg_uint32) (card_status & CARD_STATE)) >> CARD_STATE_SHIFT);
545 if(card_status == TRAN)
558 if ((bus_width == FOUR ) || (bus_width == ONE))
560 /* Configure CMD55 for SD card */
561 configure_cmd(&cmd,CMD55,card_address,READ,RESPONSE_48_CRC, DISABLE, ONE);
563 /* Issue CMD55 to SD Memory card*/
564 if(send_cmd_and_wait_resp(&cmd) == FAIL)
571 /* Read Command response */
572 read_response(RESPONSE_48_CRC, &resp);
573 read_resp = resp.rsp0;
574 if(read_resp & SD_R1_APP_CMD_MSK)
576 bus_width = (bus_width>>ONE);
578 /* Configure ACMD6 for SD card */
579 configure_cmd(&cmd,ACMD6,bus_width,READ,RESPONSE_48_CRC, DISABLE, ONE);
580 /* Send ACMD6 to SD Memory card*/
581 if(send_cmd_and_wait_resp(&cmd) == FAIL)
597 static cyg_uint32 check_mmc(void)
601 //cyg_uint32 response;
603 cyg_uint32 ocr_value=0;
604 cyg_uint32 status = FAIL;
607 while((count < 10) && (status != PASS))
609 /* Configure CMD1 for MMC card */
610 configure_cmd(&cmd, CMD1, OCR_VALUE, READ, RESPONSE_48_WITHOUT_CRC,DISABLE, ONE);
612 /* Issue CMD1 to MMC card to determine OCR value */
613 if(send_cmd_and_wait_resp(&cmd) == FAIL)
617 diag_printf1("CMD1 FAIL!\n");
623 read_response(RESPONSE_48_WITHOUT_CRC, &resp);
624 ocr_value = resp.rsp0;
626 /* Mask OCR value against 0x00FF8000 and compare with response*/
627 if ((ocr_value & OCR_VALUE_MASK) == OCR_VALUE_MASK)
629 /* Check if card busy bit is cleared or not */
630 if(ocr_value & CARD_BUSY)
649 static cyg_uint32 check_card(cyg_uint32 bus_width)
652 cyg_uint32 status = FAIL;
657 diag_printf1("check SD\n");
658 if(check_sd() == PASS){
660 diag_printf1("SD init\n");
661 status = sd_init(bus_width);
662 Card_type = ((csd.csd3 & CSD_STRUCT_MSK)? SD_CSD_2_0: SD_CSD_1_0);
664 /* Card Command Class */
665 CCC = csd_get_value(&csd, 84, 95);
670 diag_printf1("check MMC\n");
671 if(check_mmc() == PASS){
675 Card_type = ((csd.csd3 & CSD_STRUCT_MSK) >> CSD_STRUCT_SHIFT) + SD_CSD_2_0;
676 /* Card Command Class */
677 CCC = csd_get_value(&csd, 84, 95);
683 static void sdhc_init(cyg_uint32 base_address)
685 cyg_uint32 iomux_base = 0x43FAC000;
686 cyg_uint32 gpio_base = 0x53FA4000;
687 cyg_uint32 iomux_sw_mux_ctl1 = readl(iomux_base + 0x18);
688 cyg_uint32 iomux_sw_mux_ctl2 = readl(iomux_base + 0x1C);
691 iomux_sw_mux_ctl1 &= 0x000000FF;
692 iomux_sw_mux_ctl1 |= 0x12121200;
693 writel(iomux_sw_mux_ctl1, iomux_base + 0x18);
695 iomux_sw_mux_ctl2 &= 0xFF000000;
696 iomux_sw_mux_ctl2 |= 0x00121012;
697 writel(iomux_sw_mux_ctl2, iomux_base + 0x1C);
699 writel(0x0A529485, iomux_base + 0x168);
700 writel(0x0A5294A5, iomux_base + 0x16c);
702 /* Initialize base address */
703 pSDHC = (psdhc_t)base_address;
706 static void sdhc_reset(void)
708 pSDHC->sdhc_clk = SDHC_CLK_RESET;
709 pSDHC->sdhc_clk = SDHC_CLK_RESET | SDHC_CLK_STOP;
710 pSDHC->sdhc_clk = SDHC_CLK_STOP;
711 pSDHC->sdhc_clk = SDHC_CLK_STOP;
712 pSDHC->sdhc_clk = SDHC_CLK_STOP;
713 pSDHC->sdhc_clk = SDHC_CLK_STOP;
714 pSDHC->sdhc_clk = SDHC_CLK_STOP;
715 pSDHC->sdhc_clk = SDHC_CLK_STOP;
716 pSDHC->sdhc_clk = SDHC_CLK_STOP;
717 pSDHC->sdhc_clk = SDHC_CLK_STOP;
720 static cyg_uint32 card_reset(void)
724 configure_clk(iden_mode);
726 /*set size of read and response fifo */
727 //pSDHC->sdhc_read_to = 0xffff;
728 pSDHC->sdhc_read_to = 0x2DB4;
729 pSDHC->sdhc_response_to = 0xff;
732 /* CMD0 to reset SD/MMC cards */
733 configure_cmd(&cmd,CMD0,NO_ARG,READ, RESPONSE_NO, DISABLE, ONE);
735 return send_cmd_and_wait_resp(&cmd);
738 static void wait_transfer_done(cyg_uint32 mask)
740 /* Wait interrupt (WRITE_OP_DONE/READ_OP_DONE) */
741 while(!(pSDHC->sdhc_status & mask));
744 static cyg_uint32 check_data(cyg_uint32 done_mask, cyg_uint32 crc_err_code_mask, cyg_uint32 crc_err_mask)
746 cyg_uint32 status = FAIL;
747 /* Check whether the interrupt is an OP_DONE or a data time out or a CRC error */
748 if((pSDHC->sdhc_status & done_mask) &&
749 !(pSDHC->sdhc_status & crc_err_code_mask) &&
750 !(pSDHC->sdhc_status & crc_err_mask))
761 static cyg_uint32 check_card_status(void)
764 cyg_uint32 status = PASS;
765 cyg_uint32 card_state;
766 cyg_uint32 read_resp;
768 //cyg_uint32 card_address = (Card_rca << RCA_SHIFT);
770 configure_cmd(&cmd,CMD13,card_address,READ,RESPONSE_48_CRC, DISABLE, ONE);
772 if(send_cmd_and_wait_resp(&cmd) == FAIL)
778 /* Read Command response */
779 read_response (RESPONSE_48_CRC, &resp);
780 read_resp = resp.rsp0;
781 card_state = ((cyg_uint32) (read_resp & CARD_STATE) >> CARD_STATE_SHIFT);
783 if(card_state == TRAN)
797 /*==========================================================================
798 FUNCTION: static cyg_uint32 card_get_capacity_size(void)
800 this function will analize MMC/SD CSD register and return the capacity size (in unit of KB)
814 Detailed Description:
815 ==============================================================================*/
816 cyg_uint32 card_get_capacity_size (void)
818 cyg_uint32 capacity = 0;
819 cyg_uint32 c_size, c_size_mult, blk_len;
821 if(!csd.csd0 && !csd.csd1 && !csd.csd2 && !csd.csd3)
822 diag_printf("WARNINGS:card_init should be done first!\n");
831 c_size = csd_get_value(&csd, 62, 73);
832 c_size_mult = csd_get_value(&csd, 47, 49);
833 blk_len = csd_get_value(&csd, 80, 83);
834 capacity = (((c_size+1) << (c_size_mult +2)) << blk_len) / 1024;
835 diag_printf1("c_size=0x%x, c_size_mult=0x%x, blk_len=0x%x, capacity(KB)=0x%x\n",
836 c_size, c_size_mult, blk_len, capacity);
840 //blk_len = csd_get_value(&csd, 80, 83);
841 c_size = csd_get_value(&csd, 48, 69);
842 capacity = (c_size + 1) * 512; // block length is fixed to 512B
843 diag_printf1("card capacity2=0x%x\n", capacity);
849 if (capacity > (0x80000000 / 1024))
850 HighCapacityCard = 1;
852 HighCapacityCard = 0;
857 cyg_uint32 mxcmci_init (cyg_uint32 bus_width, cyg_uint32 base_address)
859 sdhc_init(base_address);
861 /* Software Reset to SDHC */
864 /* Software Reset to card */
867 return check_card(bus_width);
870 cyg_uint32 mmc_data_read (cyg_uint32 *ram_ptr, cyg_uint32 length, cyg_uint32 offset)
873 cyg_uint32 len, retry = 15;
874 cyg_uint32 status = PASS;
875 cyg_uint32 i, j, k = 0;
877 diag_printf1("\ncard_data_read !-- offset: %x, length: %x \n", offset, length);
879 len = (length + BLOCK_LEN - 1) & (~(BLOCK_LEN - 1));
881 if (HighCapacityCard)
882 offset = offset / 512;
884 /* Configure SDHC block and number of blocks */
885 pSDHC->sdhc_blk_len = BLOCK_LEN;
886 pSDHC->sdhc_nob = 0x1;
888 /* Configure CMD16 to set block length as 512 bytes.*/
889 configure_cmd(&cmd,CMD16,BLOCK_LEN,READ,RESPONSE_48_CRC, DISABLE, ONE);
890 if(send_cmd_and_wait_resp(&cmd) == FAIL)
893 diag_printf1("CMD16 Fail!\n");
897 while(len != 0 && !status)
899 //check card status whether it is in transfer mode, so as to start next transfer
900 while((status = check_card_status())!=PASS);
902 diag_printf1("length left: %x \n", len);
904 /* Send CMD17 for single block read */
905 configure_cmd(&cmd,CMD17,offset,READ,RESPONSE_48_CRC, ENABLE, ONE);
906 if(send_cmd_and_wait_resp(&cmd) == FAIL)
909 diag_printf1("CMD17 Fail!\n");
914 pSDHC->sdhc_int_cntr = SDHC_INT;
915 for(i = 0; i < BLOCK_LEN/16; i++)
917 /* Wait for BRR bit to be set */
918 while(!(pSDHC->sdhc_status & SDHC_STATUS_BUF_READ_RDY_MSK)) {
923 /* Read 32 bit data from buffer access fifo */
924 *ram_ptr = pSDHC->sdhc_buffer_access;
928 /* Wait for transfer complete */
929 wait_transfer_done(SDHC_STATUS_READ_OP_DONE_MSK);
931 /* Check for status errors (crc or timeout)*/
932 status = check_data(SDHC_STATUS_READ_OP_DONE_MSK, SDHC_STATUS_TIME_OUT_READ, SDHC_STATUS_READ_CRC_ERR_MSK);
934 offset = offset + BLOCK_LEN;
935 len = len - BLOCK_LEN;
936 //ram_ptr= ram_ptr + (BLOCK_LEN/4);
937 diag_printf1("length left3: %x \n", len);
941 diag_printf1("End of card data read!\n");
945 cyg_uint32 mmc_data_write (cyg_uint32 *ram_ptr, cyg_uint32 length, cyg_uint32 offset)
949 cyg_uint32 status = PASS;
952 len = (length + BLOCK_LEN - 1) & (~(BLOCK_LEN - 1));
954 /* Configure SDHC block and number of blocks */
955 pSDHC->sdhc_blk_len = BLOCK_LEN;
956 pSDHC->sdhc_nob = 0x1;
958 /* high capacity card uses sector mode */
959 if (HighCapacityCard)
960 offset = offset / 512;
962 /* Send CMD16 to set block length as 512 bytes.*/
963 configure_cmd(&cmd,CMD16,BLOCK_LEN,READ,RESPONSE_48_CRC, DISABLE, ONE);
964 if(send_cmd_and_wait_resp(&cmd) == FAIL)
970 while(len != 0 && !status)
972 //check card status whether it is in transfer mode, so as to start next transfer
973 while((status = check_card_status())!=PASS);
974 /* Comfigure command CMD24 for block write--write address */
975 configure_cmd(&cmd,CMD24,offset,WRITE,RESPONSE_48_CRC, ENABLE, ONE);
976 if(send_cmd_and_wait_resp(&cmd) == FAIL)
983 pSDHC->sdhc_int_cntr = SDHC_INT;
985 for(i = 0; i < (BLOCK_LEN)/4; i++)
987 /* Wait for BWR bit to be set */
988 while(!(pSDHC->sdhc_status & SDHC_STATUS_BUF_WRITE_RDY_MSK));
989 //copy data from ram to sdhc buffer access fifo
990 pSDHC->sdhc_buffer_access = *ram_ptr;
994 /* Wait for transfer done */
995 wait_transfer_done(SDHC_STATUS_WRITE_OP_DONE_MSK);
997 /* Check for status errors (crc or timeout)*/
998 status = check_data(SDHC_STATUS_WRITE_OP_DONE_MSK, 0, SDHC_STATUS_WRITE_CRC_ERR_MSK);
1000 len = len - BLOCK_LEN;
1001 offset += BLOCK_LEN;
1002 //ram_ptr = ram_ptr + (BLOCK_LEN/4);
1009 cyg_uint32 mmc_data_erase (cyg_uint32 offset, cyg_uint32 size)
1012 cyg_uint32 startEraseBlockCmd;
1013 cyg_uint32 endEraseBlockCmd;
1014 cyg_uint32 startBlock = offset/BLOCK_LEN;
1015 cyg_uint32 endBlock = (offset+size)/BLOCK_LEN;
1016 cyg_uint32 status = FAIL;
1018 /* Fix erase operation on MX31/32 */
1020 if(Card_Mode == MMC) {
1021 startBlock *=BLOCK_LEN;
1022 endBlock *= BLOCK_LEN;
1023 startEraseBlockCmd = CMD35;
1024 endEraseBlockCmd = CMD36;
1026 else if(Card_Mode == SD) {
1027 startBlock *=BLOCK_LEN;
1028 endBlock *= BLOCK_LEN;
1029 startEraseBlockCmd = CMD32;
1030 endEraseBlockCmd = CMD33;
1032 if (HighCapacityCard) {
1033 startBlock /= BLOCK_LEN;
1034 endBlock /= BLOCK_LEN;
1037 /* Configure start erase command to set first block*/
1038 configure_cmd(&cmd,startEraseBlockCmd,startBlock,READ,RESPONSE_48_CRC, DISABLE, ONE);
1039 if((status = send_cmd_and_wait_resp(&cmd)) == PASS){
1041 /* Configure end erase command to set end block*/
1042 configure_cmd(&cmd,endEraseBlockCmd,endBlock,READ,RESPONSE_48_CRC, DISABLE, ONE);
1043 if((status = send_cmd_and_wait_resp(&cmd)) == PASS){
1044 /* Comfigure command to start erase*/
1045 configure_cmd(&cmd,CMD38,0,READ,RESPONSE_48_CRC, DISABLE, ONE);
1046 if((status = send_cmd_and_wait_resp(&cmd)) == PASS){
1047 //wait for completion
1056 cyg_uint32 card_flash_query(void* data)
1059 cyg_uint32 status = PASS;
1060 response_t response;
1062 // Configure CMD2 for card No Argument is expected for CMD2
1063 configure_cmd(&cmd,CMD2,NO_ARG,READ,RESPONSE_136, DISABLE, ONE);
1065 // Send CMD2 to card to determine CID contents
1066 if(send_cmd_and_wait_resp(&cmd) == FAIL)
1069 diag_printf("%s: can't send query command\n", __FUNCTION__);
1073 cyg_uint32* d = (cyg_uint32*)data;
1074 // Read Command response
1075 read_response (RESPONSE_136, &response);
1077 // Assign CID values to mmc_cid structures
1078 *d++ = response.rsp0;
1079 *d++ = response.rsp1;
1080 *d++= response.rsp2;
1083 // Assign cid_request as SUCCESS
1086 diag_printf( "%s(PASS?=%d):(ID=0x%x: 0x%x, 0x%x, 0x%x)\n",
1087 __FUNCTION__, status,*(cyg_uint32*)(data), *(cyg_uint32*)((cyg_uint32)data+4),
1088 *(cyg_uint8*)((cyg_uint32)data+8), *(cyg_uint8*)((cyg_uint32)data+12));