| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758 |
- #include "wm_sdio_host.h"
- #include "wm_debug.h"
- #include "wm_mem.h"
- #include "wm_dma.h"
- #include "wm_cpu.h"
- #define TEST_DEBUG_EN 0
- #if TEST_DEBUG_EN
- #define TEST_DEBUG(fmt, ...) printf("%s: "fmt, __func__, ##__VA_ARGS__)
- #else
- #define TEST_DEBUG(fmt, ...)
- #endif
- SD_CardInfo_t SDCardInfo;
- extern void delay_cnt(int count);
- static void sh_dumpBuffer(char *name, char* buffer, int len)
- {
- #if TEST_DEBUG_EN
- int i = 0;
- printf("%s:\n", name);
- for(; i < len; i++)
- {
- printf("%02X, ", buffer[i]);
- if((i + 1) % 16 == 0)
- {
- printf("\n");
- }
- }
- printf("\n");
- #endif
- }
- void wm_sdh_send_cmd(uint8_t cmdnum, uint32_t cmdarg, uint8_t mmcio)
- {
- SDIO_HOST->CMD_BUF[4] = cmdnum | 0x40;
- SDIO_HOST->CMD_BUF[3] = (cmdarg >> 24) & 0xFF;
- SDIO_HOST->CMD_BUF[2] = (cmdarg >> 16) & 0xFF;
- SDIO_HOST->CMD_BUF[1] = (cmdarg >> 8) & 0xFF;
- SDIO_HOST->CMD_BUF[0] = (cmdarg & 0xFF);
- SDIO_HOST->MMC_INT_SRC |= 0x7ff; // clear all firstly
- SDIO_HOST->MMC_IO = mmcio;
- }
- void wm_sdh_get_response(uint32_t * respbuf, uint32_t buflen)
- {
- int i = 0;
- for(i = 0; i < buflen; i++)
- {
- respbuf[i] = (SDIO_HOST->CMD_BUF[i*4 + 3] << 24) | (SDIO_HOST->CMD_BUF[i*4 + 2] << 16) | (SDIO_HOST->CMD_BUF[i*4 + 1] << 8) | (SDIO_HOST->CMD_BUF[i*4]);
- }
- }
- static int sm_sdh_wait_interrupt(uint8_t srcbit, int timeout)
- {
- int ret = 0;
- unsigned int tmp = (1 << srcbit);
- volatile int vtimeout= timeout;
- if(vtimeout == -1) {
- vtimeout = 0x7FFFF;
- }
- while(1)
- {
- if(SDIO_HOST->MMC_INT_SRC & tmp)
- {
- SDIO_HOST->MMC_INT_SRC |= tmp;
- if(SDIO_HOST->MMC_INT_SRC)
- {
- TEST_DEBUG("Err Int 0x%x\n", SDIO_HOST->MMC_INT_SRC);
- }
- break;
- }
- vtimeout--;
- if((vtimeout == 0) || (vtimeout < 0))
- {
- ret = 1; //timeout, err
- break;
- }
- delay_cnt(1);
- }
- return ret;
- }
- int wm_sdh_config(void)
- {
- tls_sys_clk sysclk;
- tls_sys_clk_get(&sysclk);
- SDIO_HOST->MMC_CARDSEL = 0xC0 | (sysclk.cpuclk / 2 - 1);//0xd3; //enable module, enable mmcclk
- SDIO_HOST->MMC_CTL = 0x13;//0xC3; //4bits, low speed, 1/4 divider, auto transfer, mmc mode.
- SDIO_HOST->MMC_INT_MASK = 0x100; //unmask sdio data interrupt.
- SDIO_HOST->MMC_CRCCTL = 0xC0; //
- SDIO_HOST->MMC_TIMEOUTCNT = 0xff;
- SDIO_HOST->MMC_IO_MBCTL |= 0xf0;
- return 0;
- }
- int wm_sd_card_initialize(uint32_t *rca)
- {
- int ret = -1;
- uint32_t respCmd[4];
- int recnt = 5;
-
- wm_sdh_config();
- //======================================================
- // set up
- // Test: Init sequence, With response check
- // CMD 0 Reset Card
- // CMD 8 Get voltage (Only 2.0 Card response to this)
- // CMD55 Indicate Next Command are Application specific
- // ACMD41 Get Voltage windows
- // CMD 2 CID reg
- // CMD 3 Get RCA.
- //======================================================
- begin:
- //Send CMD0 + 8 null clock to reset and stablize
- for (int i = 0; i < 7 - recnt; i++)
- {
- wm_sdh_send_cmd(0, 0, 0x84);
- sm_sdh_wait_interrupt(0, -1);
- }
- delay_cnt(1000);
- wm_sdh_send_cmd(8, 0x1AA, 0xC4); //Send CMD8
- sm_sdh_wait_interrupt(0, -1);
- wm_sdh_get_response(respCmd, 2);
- sh_dumpBuffer("CMD8 respCmd", (char *)respCmd, 5);
- if(respCmd[0] != 0x1AA || (respCmd[1] & 0xFF) != 8)
- {
- TEST_DEBUG("CMD8 Error\n");
- if(recnt--)
- goto begin;
- goto end;
- }
- while(1)
- {
- wm_sdh_send_cmd(55, 0, 0xC4); //Send CMD55
- sm_sdh_wait_interrupt(0, -1);
- wm_sdh_get_response(respCmd, 2);
- sh_dumpBuffer("CMD55 respCmd", (char *)respCmd, 5);
- if((respCmd[1] & 0xFF) != 55)
- goto end;
- wm_sdh_send_cmd(41, 0xC0100000, 0xC4); //Send ACMD41
- sm_sdh_wait_interrupt(0, -1);
- sm_sdh_wait_interrupt(3, 1000); //由于sd规范中,Acmd41返回的crc永远是11111,也就是应该忽略crc;这里的crc错误应该忽略。
- wm_sdh_get_response(respCmd, 2);
- sh_dumpBuffer("ACMD41 respCmd", (char *)respCmd, 5);
- if((respCmd[1] & 0xFF) != 0x3F) //sd规范定义固定为0x3F,所以导致crc错误
- goto end;
- if(respCmd[0] >> 31 & 0x1)
- {
- TEST_DEBUG("card is ready\n");
- break;
- }
- }
- wm_sdh_send_cmd(2, 0, 0xD4); //Send CMD2
- sm_sdh_wait_interrupt(0, -1);
- sm_sdh_wait_interrupt(3, 1000);
- wm_sdh_get_response(respCmd, 4);
- sh_dumpBuffer("CMD2 respCmd", (char *)respCmd, 16);
- if((respCmd[3] >> 24 & 0xFF) != 0x3F) //sd规范定义固定为0x3F,所以导致crc错误
- goto end;
- wm_sdh_send_cmd(3, 0, 0xC4); //Send CMD3
- sm_sdh_wait_interrupt(0, -1);
- wm_sdh_get_response(respCmd, 2);
- sh_dumpBuffer("CMD3 respCmd", (char *)respCmd, 5);
- if((respCmd[1] & 0xFF) != 3)
- goto end;
- *rca = respCmd[0] >> 16;
- TEST_DEBUG("RCA = %x\n", *rca);
- ret = 0;
- end:
- return ret;
- }
- static uint32_t SD_GetCapacity(uint8_t *csd, SD_CardInfo_t *SDCardInfo)
- {
- uint32_t Capacity;
- uint16_t n;
- uint32_t csize;
- if((csd[0]&0xC0)==0x40)//判断bit126是否为1
- {
- SDCardInfo->CSDVer = 2;
- csize = csd[9] + ((uint32_t)csd[8] << 8) + ((uint32_t)(csd[7] & 63) << 16) + 1;
- Capacity = csize << 9;
- SDCardInfo->CardCapacity = (long long)Capacity*1024;
- SDCardInfo->CardBlockSize = 512;
- }
- else
- {
- SDCardInfo->CSDVer = 1;
- n = (csd[5] & 0x0F) + ((csd[10] & 0x80) >> 7) + ((csd[9] & 0x03) << 1) + 2;
- csize = (csd[8] >> 6) + ((uint16_t)csd[7] << 2) + ((uint16_t)(csd[6] & 0x03) << 10) + 1;
- Capacity = (uint32_t)csize << (n - 10);
- SDCardInfo->CardCapacity = (long long)Capacity*1024;
- SDCardInfo->CardBlockSize = 1<<(csd[5] & 0x0F);
- }
- return Capacity;
- }
- int wm_sd_card_query_csd(uint32_t rca)
- {
- int ret = -1, i;
- uint32_t respCmd[4];
- char adjustResp[16];
-
- wm_sdh_send_cmd(9, rca<<16, 0x54); //Send CMD9
- sm_sdh_wait_interrupt(0, -1);
- sm_sdh_wait_interrupt(3, 1000);
- wm_sdh_get_response(respCmd, 4);
- for(i=0; i<16; i++) adjustResp[15-i] = SDIO_HOST->CMD_BUF[i];
- SD_GetCapacity((uint8_t*)&adjustResp[1], &SDCardInfo);
- sh_dumpBuffer("CMD9 respCmd", adjustResp, 16);
- if((respCmd[3] >> 24 & 0xFF) != 0x3F) //sd规范定义固定为0x3F,所以导致crc错误
- goto end;
- ret = 0;
- end:
- return ret;
- }
- int wm_sd_card_set_blocklen(uint32_t blocklen)
- {
- int ret = -1;
- uint32_t respCmd[2];
- wm_sdh_send_cmd(16, blocklen, 0xC4); //Send CMD16
- sm_sdh_wait_interrupt(0, -1);
- wm_sdh_get_response(respCmd, 2);
- sh_dumpBuffer("CMD16 respCmd", (char *)respCmd, 5);
- if((respCmd[1] & 0xFF) != 16)
- goto end;
- ret = 0;
- end:
- return ret;
- }
- int wm_sd_card_select(uint32_t rca)
- {
- int ret = -1;
- uint32_t respCmd[2];
- wm_sdh_send_cmd(7, rca<<16, 0xC4); //Send CMD7
- sm_sdh_wait_interrupt(0, -1);
- wm_sdh_get_response(respCmd, 2);
- sh_dumpBuffer("CMD7 respCmd", (char *)respCmd, 5);
- if((respCmd[1] & 0xFF) != 7)
- goto end;
- ret = 0;
- end:
- return ret;
- }
- void wm_sd_card_deselect()
- {
- wm_sdh_send_cmd(7, 0, 0x84); //Send CMD7
- sm_sdh_wait_interrupt(0, -1);
- }
- int wm_sd_card_query_status(uint32_t rca, uint32_t *respCmd0)
- {
- int ret = -1;
- #if TEST_DEBUG_EN
- uint8_t current_state = 0;
- uint8_t error_state = 0;
- #endif
- uint32_t respCmd[2];
- wm_sdh_send_cmd(13, rca<<16, 0xC4); //Send CMD13
- sm_sdh_wait_interrupt(0, -1);
- wm_sdh_get_response(respCmd, 2);
- sh_dumpBuffer("CMD13 respCmd", (char *)respCmd, 5);
- if((respCmd[1] & 0xFF) != 13)
- goto end;
- if(respCmd0)
- {
- *respCmd0 = respCmd[0];
- }
- #if TEST_DEBUG_EN
- current_state = respCmd[0] >> 9 & 0xF;
- error_state = respCmd[0] >> 19 & 0x1;
- TEST_DEBUG("current_state %d, error_state %d\n",current_state,error_state);
- #endif
- ret = 0;
- end:
- return ret;
- }
- /*
- * speed_mode: 0: low speed; 1: high speed;
- * */
- int wm_sd_card_switch_func(uint8_t speed_mode)
- {
- int ret = -1;
- int i;
- uint32_t respCmd[2];
- wm_sdh_send_cmd(6, 0x00fffff1, 0xC4); //Send CMD6
- sm_sdh_wait_interrupt(0, -1);
- wm_sdh_get_response(respCmd, 2);
- sh_dumpBuffer("CMD6 respCmd", (char *)respCmd, 5);
- if((respCmd[1] & 0xFF) != 6)
- goto end;
- SDIO_HOST->BUF_CTL = 0x4020; //disable dma, read sd card
- SDIO_HOST->MMC_INT_SRC |= 0x7ff; // clear all firstly
- SDIO_HOST->MMC_IO = 0x83; //!!!read data, auto transfer
- sm_sdh_wait_interrupt(1, -1);
- TEST_DEBUG("read complete\n");
- for(i = 0; i < 128; i++)
- {
- respCmd[0] = SDIO_HOST->DATA_BUF[0];
- if(i == 4)
- {
- respCmd[1] = respCmd[0];
- }
- printf("0x%x, ", respCmd[0]);
- if(i % 4 == 3)
- {
- printf("\n");
- }
- }
- TEST_DEBUG("the value of byte 17~20 is 0x%x\n", respCmd[1]);
- if(respCmd[1] & 0xF) //support high speed
- {
- wm_sdh_send_cmd(6, 0x80fffff0 | speed_mode, 0xC4); //Send CMD6
- sm_sdh_wait_interrupt(0, -1);
- wm_sdh_get_response(respCmd, 2);
- sh_dumpBuffer("CMD6 respCmd", (char *)respCmd, 5);
- if((respCmd[1] & 0xFF) != 6)
- goto end;
- SDIO_HOST->BUF_CTL = 0x4020; //disable dma, read sd card
- SDIO_HOST->MMC_INT_SRC |= 0x7ff; // clear all firstly
- SDIO_HOST->MMC_IO = 0x83; //!!!read data, auto transfer
- sm_sdh_wait_interrupt(1, -1);
- TEST_DEBUG("read complete\n");
- for(i = 0; i < 128; i++)
- {
- respCmd[0] = SDIO_HOST->DATA_BUF[0];
- if(i == 4)
- {
- respCmd[1] = respCmd[0];
- }
- printf("0x%x, ", respCmd[0]);
- if(i % 4 == 3)
- {
- printf("\n");
- }
- }
- TEST_DEBUG("the value of byte 17~20 is 0x%x\n", respCmd[1]);
- if((respCmd[1] & 0xF) == speed_mode)
- {
- if(speed_mode == 1)
- {
- SDIO_HOST->MMC_CTL |= (1 << 6);
- }
- else
- {
- SDIO_HOST->MMC_CTL &= ~(1 << 6);
- }
- TEST_DEBUG("switch speed_mode %d success\n", speed_mode);
- }
- }
- ret = 0;
- end:
- return ret;
- }
- /*
- * bus_width: 0:1bit; 2:4bits
- * */
- int wm_sd_card_set_bus_width(uint32_t rca, uint8_t bus_width)
- {
- int ret = -1;
- uint32_t respCmd[2];
- if(bus_width != 0 && bus_width != 2)
- {
- TEST_DEBUG("bus width parameter error\n");
- goto end;
- }
- if(bus_width == 2)
- {
- SDIO_HOST->MMC_CTL |= (1 << 7);
- }
- else
- {
- SDIO_HOST->MMC_CTL &= ~(1 << 7);
- }
- wm_sdh_send_cmd(55, rca<<16, 0xC4); //Send CMD55
- sm_sdh_wait_interrupt(0, -1);
- wm_sdh_get_response(respCmd, 2);
- sh_dumpBuffer("CMD55 respCmd", (char *)respCmd, 5);
- if((respCmd[1] & 0xFF) != 55)
- goto end;
- wm_sdh_send_cmd(6, bus_width, 0xC4); //Send ACMD6
- sm_sdh_wait_interrupt(0, -1);
- wm_sdh_get_response(respCmd, 2);
- sh_dumpBuffer("ACMD6 respCmd", (char *)respCmd, 5);
- if((respCmd[1] & 0xFF) != 6)
- goto end;
- ret = 0;
- end:
- return ret;
- }
- int wm_sd_card_stop_trans(void)
- {
- int ret = -1;
- uint32_t respCmd[2];
- wm_sdh_send_cmd(12, 0, 0xC4); //Send CMD12
- ret = sm_sdh_wait_interrupt(0, -1);
- if(ret)
- goto end;
- wm_sdh_get_response(respCmd, 2);
- sh_dumpBuffer("CMD12 respCmd", (char *)respCmd, 5);
- if((respCmd[1] & 0xFF) != 12)
- goto end;
- ret = 0;
- end:
- return ret;
- }
- static void sdio_host_reset(void)
- {
- tls_bitband_write(HR_CLK_RST_CTL, 27, 0);
- delay_cnt(1000);
- tls_bitband_write(HR_CLK_RST_CTL, 27, 1);
- while(tls_bitband_read(HR_CLK_RST_CTL, 27) == 0);
- }
- int sdh_card_init(uint32_t *rca_ref)
- {
- int ret = -1;
- uint32_t rca = 0;
- sdio_host_reset();
-
- ret = wm_sd_card_initialize(&rca);
- if(ret)
- goto end;
- SDCardInfo.RCA = (u16)(rca & 0xFFFF);
- ret = wm_sd_card_query_csd(rca);
- if(ret)
- goto end;
- ret = wm_sd_card_query_status(rca, NULL);
- if(ret)
- goto end;
- ret = wm_sd_card_select(rca);
- if(ret)
- goto end;
- ret = wm_sd_card_query_status(rca, NULL);
- if(ret)
- goto end;
- *rca_ref = rca;
- SDIO_HOST->MMC_CTL = 0xD3;
- ret = 0;
- end:
- TEST_DEBUG("ret %d\n", ret);
- return ret;
- }
- /*buf's len must >= 512*/
- int wm_sd_card_block_read(uint32_t rca, uint32_t sd_addr, char *buf)
- {
- int ret = -1;
- int i;
- uint32_t respCmd[2];
- wm_sdh_send_cmd(17, sd_addr, 0x44); //Send CMD17
- sm_sdh_wait_interrupt(0, -1);
- wm_sdh_get_response(respCmd, 2);
- sh_dumpBuffer("CMD17 respCmd", (char *)respCmd, 5);
- if((respCmd[1] & 0xFF) != 17)
- goto end;
- SDIO_HOST->BUF_CTL = 0x4020; //disable dma, read sd card
- SDIO_HOST->MMC_INT_SRC |= 0x7ff; // clear all firstly
- SDIO_HOST->MMC_IO = 0x3; //!!!read data, auto transfer
- sm_sdh_wait_interrupt(1, -1);
- TEST_DEBUG("read complete\n");
- for(i = 0; i < 128; i++)
- {
- *((uint32_t*)(buf + 4*i)) = SDIO_HOST->DATA_BUF[0];
- }
- ret = 0;
- end:
- return ret;
- }
- /*buf's len must be 512*/
- int wm_sd_card_block_write(uint32_t rca, uint32_t sd_addr, char *buf)
- {
- int i;
- int ret = -1;
- uint32_t respCmd[2];
- uint8_t current_state = 0;
- uint8_t error_state = 0;
- wm_sdh_send_cmd(24, sd_addr, 0x44); //Send CMD24
- sm_sdh_wait_interrupt(0, -1);
- wm_sdh_get_response(respCmd, 2);
- sh_dumpBuffer("CMD24 respCmd", (char *)respCmd, 5);
- if((respCmd[1] & 0xFF) != 24)
- goto end;
- SDIO_HOST->BUF_CTL = 0x4820; //disable dma, write sd card
- for(i = 0; i < 128; i++)
- {
- SDIO_HOST->DATA_BUF[i] = *((uint32*)(buf + 4*i));
- }
- SDIO_HOST->MMC_BYTECNTL = 512;
- SDIO_HOST->MMC_INT_SRC |= 0x7ff; // clear all firstly
- SDIO_HOST->MMC_IO = 0x1; //!!!write data, auto transfer
- sm_sdh_wait_interrupt(1, -1);
- while(true)
- {
- ret = wm_sd_card_query_status(rca, &respCmd[0]);
- if(ret)
- goto end;
- current_state = respCmd[0] >> 9 & 0xF;
- error_state = respCmd[0] >> 19 & 0x1;
- if(current_state == 4) //tran
- {
- break;
- }
- if(error_state)
- {
- ret = -1;
- goto end;
- }
- }
- ret = 0;
- end:
- TEST_DEBUG("write complete err %d\n", ret);
- return ret;
- }
- /* dir: 1, write; 0, read*/
- int wm_sd_card_dma_config(u32*mbuf,u32 bufsize,u8 dir)
- {
- int ch;
- u32 addr_inc = 0;
- ch = tls_dma_request(0, NULL);
- DMA_CHNLCTRL_REG(ch) = DMA_CHNL_CTRL_CHNL_OFF;
- if(dir)
- {
- DMA_SRCADDR_REG(ch) = (unsigned int)mbuf;
- DMA_DESTADDR_REG(ch) = (unsigned int)SDIO_HOST->DATA_BUF;
- addr_inc = (1 << 1);
- }
- else
- {
- DMA_SRCADDR_REG(ch) = (unsigned int)SDIO_HOST->DATA_BUF;
- DMA_DESTADDR_REG(ch) = (unsigned int)mbuf;
- addr_inc = (1 << 3);
- }
- DMA_CTRL_REG(ch) = addr_inc | (2 << 5) | (bufsize << 8);
- DMA_MODE_REG(ch) = DMA_MODE_SEL_SDIOHOST | DMA_MODE_HARD_MODE;
- DMA_CHNLCTRL_REG(ch) = DMA_CHNL_CTRL_CHNL_ON;
-
- return ch;
- }
- static int wm_sdh_wait_blocks_done(void)
- {
- int ret = 0;
- uint32_t timeout = 0x7FFFF * 8;
- while(1)
- {
- if((SDIO_HOST->MMC_IO_MBCTL & 0x01) == 0x00)
- {
- break;
- }
-
- if(timeout == 0)
- {
- ret = -1;
- tls_os_time_delay(HZ);
- }
- else
- {
- delay_cnt(1);
- timeout--;
- }
- }
- return ret;
- }
- /*read blocks by dma
- * buflen must be integer multiple of 512
- * */
- int wm_sd_card_blocks_read(uint32_t rca, uint32_t sd_addr, char *buf, uint32_t buflen)
- {
- int ret = -1, dma_channel = 0xFF, retresp = -100;
- uint32_t respCmd[2];
- int block_cnt = buflen/512;
- uint8_t current_state = 0;
- uint8_t error_state = 0;
- wm_sdh_send_cmd(18, sd_addr, 0x44); //Send CMD18
- sm_sdh_wait_interrupt(0, -1);
- wm_sdh_get_response(respCmd, 2);
- sh_dumpBuffer("CMD18 respCmd", (char *)respCmd, 5);
- if((respCmd[1] & 0xFF) != 18)
- goto end;
- SDIO_HOST->BUF_CTL = 0x4000; //disable dma,
- dma_channel = wm_sd_card_dma_config((u32*)buf, 512*block_cnt, 0);
- SDIO_HOST->BUF_CTL = 0x404; //enable dma, read sd card
- SDIO_HOST->MMC_BLOCKCNT = block_cnt;
- SDIO_HOST->MMC_INT_SRC |= 0x7ff; // clear all firstly
- SDIO_HOST->MMC_IO_MBCTL = 0xa3; //read data, enable multi blocks data transfer
- // sm_sdh_wait_interrupt(1, -1);
- ret = wm_sdh_wait_blocks_done();
- if(ret)
- {
- TEST_DEBUG("wm_sd_card_blocks_read: timeout error\n");
- goto end;
- }
- TEST_DEBUG("read complete\n");
- ret = wm_sd_card_stop_trans();
- if(ret)
- goto end;
-
- /*waiting for card to trans state*/
- do
- {
- ret = wm_sd_card_query_status(rca, &respCmd[0]);
- if(ret)
- break;
- current_state = respCmd[0] >> 9 & 0xF;
- error_state = respCmd[0] >> 19 & 0x1;
- if(error_state)
- {
- ret = -1;
- break;
- }
- }while(current_state != 4);
- if (ret)
- {
- TEST_DEBUG("mr blocks:%x\r\n", error_state);
- goto end;
- }
- ret = 0;
- end:
- if (ret)
- {
- wm_sd_card_stop_trans();
- do
- {
- retresp = wm_sd_card_query_status(rca, &respCmd[0]);
- if(retresp)
- break;
- current_state = respCmd[0] >> 9 & 0xF;
- error_state = respCmd[0] >> 19 & 0x1;
- if(error_state)
- {
- ret = -1;
- break;
- }
- }while(current_state != 4);
- }
- tls_dma_free(dma_channel);
- return ret;
- }
- /*write blocks by dma
- * buflen must be integer multiple of 512
- * */
- int wm_sd_card_blocks_write(uint32_t rca, uint32_t sd_addr, char *buf, uint32_t buflen)
- {
- int dma_channel = 0xFF;
- int ret = -1, retresp = -100;
- uint32_t respCmd[2];
- int block_cnt = buflen/512;
- uint8_t current_state = 0;
- uint8_t error_state = 0;
- wm_sdh_send_cmd(25, sd_addr, 0x44); //Send CMD25
- ret = sm_sdh_wait_interrupt(0, -1);
- if(ret)
- goto end;
- wm_sdh_get_response(respCmd, 2);
- sh_dumpBuffer("CMD25 respCmd", (char *)respCmd, 5);
- if((respCmd[1] & 0xFF) != 25) {
- ret = -1;
- goto end;
- }
- SDIO_HOST->BUF_CTL = 0x4000; //disable dma,
- dma_channel = wm_sd_card_dma_config((u32*)buf, 512*block_cnt, 1);
- SDIO_HOST->BUF_CTL = 0xC20; //enable dma, write sd card
- SDIO_HOST->MMC_BLOCKCNT = block_cnt;
- SDIO_HOST->MMC_INT_SRC |= 0x7ff; // clear all firstly
- SDIO_HOST->MMC_IO_MBCTL = 0xa1;////write data, enable multi blocks data transfer
- #if 0
- ret = sm_sdh_wait_interrupt(1, -1);
- if(ret)
- goto end;
- #endif
- ret = wm_sdh_wait_blocks_done();
- if(ret)
- goto end;
- ret = wm_sd_card_stop_trans();
- if(ret)
- goto end;
- /*waiting for card to trans state*/
- do
- {
- ret = wm_sd_card_query_status(rca, &respCmd[0]);
- if(ret)
- break;
- current_state = respCmd[0] >> 9 & 0xF;
- error_state = respCmd[0] >> 19 & 0x1;
- if(error_state)
- {
- ret = -1;
- break;
- }
- }while(current_state != 4);
- if (ret)
- {
- TEST_DEBUG("mw blocks:%x\r\n", error_state);
- goto end;
- }
- TEST_DEBUG("write complete\n");
- ret = 0;
- end:
- if (ret)
- {
- wm_sd_card_stop_trans();
- do
- {
- retresp = wm_sd_card_query_status(rca, &respCmd[0]);
- if(retresp)
- break;
- current_state = respCmd[0] >> 9 & 0xF;
- error_state = respCmd[0] >> 19 & 0x1;
- if(error_state)
- {
- ret = -1;
- break;
- }
- }while(current_state != 4);
- }
- tls_dma_free(dma_channel);
- return ret;
- }
|