#include "sd_card.h"
#include "gw3323_sdio.h"

#define GET_SD_CAPACITY_EN          1
#define TRACE_EN                	0

#if TRACE_EN
#define TRACE(...)              	printf(__VA_ARGS__)
#else
#define TRACE(...)
#endif

#define RSP_BUSY_TIMEOUT            2400000     //大约2s
#define RSP_TIMEOUT                 6000        //大约5ms

void sd_gpio_init(u8 type);
void sd_set_fs_sdcb_addr( sdcb_t* ptr);
bool sd_wait_finish(void *sdcb, uint timeout);
u32 cid_flag = 0;

AT(.text.sdio)
bool sd_read_wait(sdcb_t *sdcb)
{
    bool res;
    TRACE("sd wait\n");
//    while (sdio_data_pending(sdcb)) {
//    }
//    TRACE("sd wait ok\n");
//    return true;

    sdcb->card.flag_w2dat = 1;
    res = sd_wait_finish(sdcb, 100);                     //wait for finish, timeout 500ms
    sdcb->card.flag_w2dat = 0;
    if(sdio_get_flag(SDIO_FLAG_DATA_CRC_ERROR)) {
        TRACE("READ CRC ERROR!\n");
        //sdcb->card.abend = 1;
        sdio_clear_flag(SDIO_FLAG_DATA_FINISH);             //CLR PND

        return false;
    }
    if (sdcb->card.abend) {
        sdio_clear_flag(SDIO_FLAG_DATA_FINISH);             //CLR PND
        sdio_cmd(DISABLE);                                  //Disable SD controller
        res = false;
    }
    return res;
}

AT(.text.sdio)
bool sd_write_wait(sdcb_t *sdcb)
{
    bool res;
    TRACE("sd wait\n");
//    while (sdio_data_pending(sdcb)) {
//    }
//    TRACE("sd wait ok\n");
//    return true;

    sdcb->card.flag_w2dat = 1;
    res = sd_wait_finish(sdcb, 200);      //wait for finish, timeout 1s
    sdcb->card.flag_w2dat = 0;
    if (sdio_get_send_data_crc_sta() != SDIO_SEND_DATA_CRC_STA_OK) {
        TRACE("WRITE CRC ERROR!\n");
//        sdcb->card.abend = 1;
        sdio_clear_flag(SDIO_FLAG_DATA_FINISH); //CLR PND
        return false;
    }
    if (sdcb->card.abend) {
        sdio_clear_flag(SDIO_FLAG_DATA_FINISH); //CLR PND
        res = false;
    }
    return res;
}

bool sdio_req(sdcb_t *sdcb, uint8_t cmd, uint32_t arg, SDIO_RESPONSE_TYPEDEF rsp_type, FLAG_STATE ccbusy_en, FLAG_STATE ck8_en )
{
    uint time_out;
    sdio_cmd_init_typedef sdio_cmd_init_struct;
    sdio_cmd_init_struct.rsp_type = rsp_type;
    sdio_cmd_init_struct.cmd_index = cmd;
    sdio_cmd_init_struct.argument = arg;
    sdio_cmd_init_struct.ck8_en = ck8_en;
    sdio_cmd_init_struct.ccbusy_en = ccbusy_en;
    time_out = (ccbusy_en) ? RSP_BUSY_TIMEOUT : RSP_TIMEOUT;
    sdio_send_command(&sdio_cmd_init_struct);
        while (sdio_req_pending(sdcb)) {                            //Wait PND
 //       wdt_clear();
        if (--time_out == 0) {
            TRACE("cmd time out\n");
            sdcb->card.abend = 1;
            return false;
        }
    }
    return !(sdio_get_flag(SDIO_FLAG_NO_RESPONSE));
}

bool sdio_req_pending(sdcb_t *sdcb)
{
    if (sdio_get_flag(SDIO_FLAG_CMD_FINISH)) {
        sdio_clear_flag(SDIO_FLAG_CMD_FINISH);
        return false;
    }
    return true;
}

//SD Read DMA KICK
 AT(.text.sdio)
 void sdio_read_kick(sdcb_t *sdcb, void *buf)
 {
//     sdio_read_data(buf, 512);
 }

//SD Write DMA KICK
 AT(.text.sdio)
 void sdio_write_kick(sdcb_t *sdcb, void *buf)
 {
//     sdio_write_data(buf, 512);
 }

//SD Write DMA KICK
AT(.text.sdio)
bool sdio_isbusy(sdcb_t *sdcb)
{
    return sdio_get_flag(SDIO_FLAG_DATA_FINISH);
}

//复位
AT(.text.sdio)
void sd_go_idle_state(sdcb_t *sdcb)
{
    sd_send_cmd_no_rsp(sdcb, 0, 0x00);
}

//MMC激活状态查询
AT(.text.sdio)
bool mmc_send_op_cond(sdcb_t *sdcb)
{
    return sd_send_cmd_r3(sdcb, 1, 0x40ff8000);
}

//广播获取CID，主要是为了状态机切换
AT(.text.sdio)
void sd_req_all_send_cid(sdcb_t *sdcb)
{
    if(sd_send_cmd_r2(sdcb, 2, 0)){
        cid_flag = sdio_get_response(SDIO_RESP3) + sdio_get_response(SDIO_RESP4);
    } else {
        cid_flag = 0;
    }

}

//SD由主机向从机获取RCA地址
AT(.text.sdio)
void sd_send_relative_addr(sdcb_t *sdcb)
{
    sd_send_cmd_r6(sdcb, 3, 0);
    sdcb->card.rca = sdio_get_response(SDIO_RESP1) & 0xFFFF0000;
}

//MMC由主机设置RCA地址
AT(.text.sdio)
void mmc_set_relative_addr(sdcb_t *sdcb)
{
    sdcb->card.rca = 0x00010000;
    sd_send_cmd_r1(sdcb, 3, sdcb->card.rca);
}

//自动识别SD/MMC来获取或发送地址
void sd_relative_addr_auto(sdcb_t *sdcb)
{
    if (sdcb->card.type == TYPE_MMC) {
        mmc_set_relative_addr(sdcb);
    } else {
        sd_send_relative_addr(sdcb);
    }
}

//SD卡进入StandBy状态
AT(.text.sdio)
void sd_select_card(sdcb_t *sdcb)
{
    sd_send_cmd_r1b(sdcb, 7, sdcb->card.rca);
}

//判断是否为SDHC卡
AT(.text.sdio)
bool sd_req_send_if_cond(sdcb_t *sdcb)
{
    return sd_send_cmd_r7(sdcb, 8, 0x000001AA);
}

#if GET_SD_CAPACITY_EN
static u16 get_sdcard_csize(sdcb_t *sdcb)
{
    u16 csize;
    csize  =  (sdio_get_response(SDIO_RESP2) & 0x000003ff) << 2;                        //rspbuf[7], rspbuf[8]
    csize |= ((sdio_get_response(SDIO_RESP3) & 0xc0000000) >> 30);                      //rspbuf[9]
    return csize;
}

static u8 get_sdcard_clen(sdcb_t *sdcb)
{
    u8 clen, blklen;
    blklen =  (sdio_get_response(SDIO_RESP2) >> 16) & 0x0f;                             //rspbuf[6]
    clen   =  (sdio_get_response(SDIO_RESP3) & 0x00038000) >> 15;                       //rspbuf[10], rspbuf[11]
    clen   = clen + blklen - 7;
    return clen;
}

AT(.text.sdio)
void get_sd_capacity(sdcb_t *sdcb)
{
    u16 csize;
    u8 clen;
    if (sdcb->card.flag_sdhc) {
        //csd 2.0 HC
        sdcb->card.capacity  =  (sdio_get_response(SDIO_RESP2) << 16) & 0x00ff0000;     //rspbuf[8]
        sdcb->card.capacity |= ((sdio_get_response(SDIO_RESP3) >> 16) & 0x0000ffff);    //rspbuf[9], rspbuf[10]
        sdcb->card.capacity += 1;
        sdcb->card.capacity <<= 10;
    } else {
        //csd 1.0 or csd2.0 LC
        csize = get_sdcard_csize(sdcb);
        clen  = get_sdcard_clen(sdcb);
        sdcb->card.capacity = ((u32)(csize + 1)) << clen;
    }
}

AT(.text.sdio)
void get_mmc_capacity(sdcb_t *sdcb)
{
    u16 csize;
    u8 clen;

    csize = get_sdcard_csize(sdcb);
    if (csize == 0xffff) {
        //Capacity > 2G
        sdcb->card.flag_sdhc = 1;
        sdcb->card.capacity = 0;
    } else {
        clen  = get_sdcard_clen(sdcb);
        sdcb->card.capacity = ((u32)(csize + 1)) << clen;
    }
}
#endif

//获取卡的CSD信息
AT(.text.sdio)
void sd_req_send_csd(sdcb_t *sdcb)
{
    sd_send_cmd_r2(sdcb, 9, sdcb->card.rca);

#if GET_SD_CAPACITY_EN
    if (sdcb->card.type == TYPE_MMC) {
        get_mmc_capacity(sdcb);
    } else {
        get_sd_capacity(sdcb);
    }
    TRACE("sd capacity: %d\n", sdcb->card.capacity);     //sectors
#else
    sdcb->card.capacity = 0xfffffff0;
#endif // GET_SD_CAPACITY_EN
}

//停止SD卡的读写状态，回到StandBy
AT(.text.sdio)
void sd_stop_transmission(sdcb_t *sdcb)
{
    sdio_clk_keep_out_cmd(ENABLE);                     //KEEP CLK OUT
    sd_send_cmd_r1b(sdcb, 12, 0);
    sdio_clk_keep_out_cmd(DISABLE);                    //CLK SUSPEND
}

//获取SD卡的状态
AT(.text.sdio)
void sd_send_status(sdcb_t *sdcb)
{
    sd_send_cmd_r1(sdcb, 13, sdcb->card.rca);
}

//SD多块读命令
AT(.text.sdio)
bool sd_read_multiple_block(sdcb_t *sdcb, u32 lba)
{
    return sd_send_cmd_mult_read(sdcb, 18, lba);
}

//SD多块写命令
AT(.text.sdio)
bool sd_write_multiple_block(sdcb_t *sdcb, u32 lba)
{
    return sd_send_cmd_r1(sdcb, 25, lba);
}

//SD扩展应用命令
AT(.text.sdio)
bool sd_app_cmd(sdcb_t *sdcb)
{
    return sd_send_cmd_r1(sdcb, 55, sdcb->card.rca);
}

//SD 1.0 激活状态查询 HCS=0
AT(.text.sdio)
bool sd_send_op_cond_0(sdcb_t *sdcb)
{
    if (sd_app_cmd(sdcb)) {
        if (sd_send_cmd_r3(sdcb, 41, 0x00ff8000)) {
            return true;
        }
    }
    return false;
}

//SD 2.0 激活状态查询 HCS=1
AT(.text.sdio)
bool sd_send_op_cond_1(sdcb_t *sdcb)
{
    if (sd_app_cmd(sdcb)) {
        if (sd_send_cmd_r3(sdcb, 41, 0x40ff8000)) {
            return true;
        }
    }
    return false;
}

//设置SD CLK的波特率
// AT(.text.sdio)
// void sdio_setbaud(sdcb_t *sdcb, uint baud)
// {
//     sdio_set_baud(sysclk_update_baud(baud));
// }

//SD配置初始化
AT(.text.sdinit)
void sdcfg_init(sdcfg_t *sdcfg)
{
    sdcfg->go_ready_retry = 200;        //就绪等待时间
    sdcfg->identification_retry = 5;    //识别重试次数
    sdcfg->rw_retry = 3;                //读写重试次数
    sdcfg->rw_init_retry = 3;           //读写重试次数
    sdcfg->stop_retry = 5;              //STOP命令重试次数
    sdcfg->rw_need_stop = 0;
}

volatile u8 sd_gpio_init_type = 0;      //SD 软件检测用到

AT(.com_text.sdio.init)
void sd_gpio_init_ex(u8 type)
{
    sd_gpio_init_type = type;
    sd_gpio_init(type);
}

//SD函数指针初始化
AT(.text.sdfunc)
void sdfunc_init(sdfunc_t *sdfunc)
{
    sdfunc->read_wait  = sd_read_wait;
    sdfunc->write_wait = sd_write_wait;
    sdfunc->port_init  = sd_gpio_init_ex;//sd_gpio_init;
}

//SD模块初始化
AT(.text.sdinit)
void sd_sdio_init(sdcb_t *sdcb)
{
    sdcb->sdfunc->port_init(0);
    clock_gate0_cmd(CLOCK_GATE0_SD0, ENABLE);
    TRACE("sd_sdio_init\n");
    sdio_cmd(DISABLE);                  //SDC DIS
    delay_us(20);
    sdio_cmd(ENABLE);                   //SDC EN
    //sfr[SDCON] |= BIT(5);             //CRC CHECK
    sdio_set_baud((24000000/300000) - 1);// 240kHz
    sdio_clk_keep_out_cmd(ENABLE);      //KEEP CLK OUT
    sdio_data_it_cmd(ENABLE);           //sd data interrupt enable
    delay_5ms(8);
}

//SD卡类型识别，通过轮流发送 CMD8 ACMD41 CMD1 三条命令来进行识别
AT(.text.sdinit)
bool sd_type_identification(sdcb_t *sdcb)
{
    uint retry = sdcb->sdcfg->identification_retry;
    while (retry--) {
        sd_go_idle_state(sdcb);
        if (sd_req_send_if_cond(sdcb)) {
            if (sdio_get_cmd_response() == 0x08) {
                TRACE("sdcard2.0\n");
                sdcb->card.type = TYPE_SD_2;
                return true;        //SD 2.0
            }
            TRACE("send_if_cond err\n");
            continue;
        }
        if (sd_send_op_cond_0(sdcb)) {
            TRACE("sdcard1.0\n");
            sdcb->card.type = TYPE_SD_1;
            return true;            //SD 1.0
        }
        sd_go_idle_state(sdcb);
        if (mmc_send_op_cond(sdcb)) {
            TRACE("mmccard\n");
            sdcb->card.type = TYPE_MMC;
            return true;            //MMC
        }
        delay_5ms(4);
    }
    TRACE("invalid card\n");
    return false;                   //INVALID
}

//查询SD卡就绪
AT(.text.sdinit)
bool sd_go_ready_try(sdcb_t *sdcb)
{
    switch (sdcb->card.type) {
    case TYPE_SD_1:
        sd_send_op_cond_0(sdcb);
        break;

    case TYPE_SD_2:
        sd_send_op_cond_1(sdcb);
        break;

    case TYPE_MMC:
        mmc_send_op_cond(sdcb);
        break;
    }
    if (0 == (sdio_get_response(SDIO_RESP1) & BIT(31))) {
        return false;           //卡未就绪
    }
    if ((sdcb->card.type == TYPE_SD_2) && (sdio_get_response(SDIO_RESP1) & BIT(30))) {
        sdcb->card.flag_sdhc = 1;
        TRACE("sdhc card\n");
    }
    return true;                //卡就绪
}

//等待SD卡就绪
AT(.text.sdinit)
bool sd_go_ready(sdcb_t *sdcb)
{
    uint retry = sdcb->sdcfg->go_ready_retry;
    if (sdcb->card.type == TYPE_INVALID) {
        return false;           //无效的类型
    }
    while (retry--) {
        if (sd_go_ready_try(sdcb)) {
            return true;        //卡就绪
        }
        delay_5ms(4);
    }
    return false;               //超时未就绪
}

AT(.text.sdinit)
bool sd_try_init(sdcb_t *sdcb)
{
    //卡状态正常时, 发CMD13查询状态作为检测.
    if (sdcb->card.online && (!sdcb->card.abend) && (sdcb->card.sta == DEV_STA_OK)) {
        static bool res = false;
        if (sd_gpio_init_type > 1) {  //2 or 3, sd is idle
           sd_send_cmd_r1(sdcb, 13, sdcb->card.rca);
        }
        return res;
    }
    //当然卡不正常时,通过轮流发送 CMD8 ACMD41 CMD1 三条命令来进行识别
    sdcb->card.abend = 0;
    sdcb->card.flag_sdhc = 0;
    sdcb->card.rca = 0;
    sdcb->card.support_4bit = 0;
    sdcb->card.rw_sta = RW_IDLE;
    sdcb->card.capacity = 0;

    //sd_init
    sdcb->sdfunc->port_init(0);
    sdio_cmd(DISABLE);
    delay_us(20);
    sdio_cmd(ENABLE);
    //sfr[SDCON] |= BIT(5);             //CRC CHECK
    sdio_set_baud((24000000/300000) - 1);// 240kHz
    sdio_clk_keep_out_cmd(ENABLE);      //KEEP CLK OUT
    sdio_data_it_cmd(ENABLE);           //sd data interrupt enable
    delay_us(20);
    sd_go_idle_state(sdcb);
    if (sd_req_send_if_cond(sdcb)) {
        if (sdio_get_cmd_response() == 0x08) {
            TRACE("sdcard2.0\n");
            sdcb->card.type = TYPE_SD_2;
            return true;        //SD 2.0
        }
        TRACE("send_if_cond err\n");
        return false;
    }
    if (sd_send_op_cond_0(sdcb)) {
        TRACE("sdcard1.0\n");
        sdcb->card.type = TYPE_SD_1;
        return true;            //SD 1.0
    }
    sd_go_idle_state(sdcb);
    if (mmc_send_op_cond(sdcb)) {
        TRACE("mmccard\n");
        sdcb->card.type = TYPE_MMC;
        return true;            //MMC
    }
    return false;
}

//SD卡初始化
AT(.text.sdinit)
bool sd_init(sdcb_t *sdcb)
{
    TRACE("sd_init\n");

    if (!sdcb->card.online) {
        return false;
    }
    sdcb->card.abend = 0;
    sdcb->card.flag_sdhc = 0;
    sdcb->card.rca = 0;
    sdcb->card.support_4bit = 0;
    sdcb->card.rw_sta = RW_IDLE;
    sdcb->card.capacity = 0;
    sd_sdio_init(sdcb);                            //SD IO的相关初始化
    if (!sd_type_identification(sdcb)) {
        sdcb->sdfunc->port_init(2);
        return false;                           //识别卡的类型失败
    }
    if (!sd_go_ready(sdcb)) {
        sdcb->sdfunc->port_init(2);
        return false;                           //卡无法就绪
    }
    sd_req_all_send_cid(sdcb);
    sd_relative_addr_auto(sdcb);
    sd_req_send_csd(sdcb);
    sd_select_card(sdcb);
    sdio_set_baud((24000000/12000000) - 1);//12MHz
    sdio_clk_keep_out_cmd(DISABLE);             //CLK Suspend

    sdcb->card.sta = DEV_STA_OK;                //初始化OK
    sdcb->sdfunc->port_init(2);
    return true;
}

//SD发送多块读命令
AT(.text.sdread)
void sd_read_send_cmd(sdcb_t *sdcb, uint lba)
{
    u32 addr = lba;
    uint retry_times = 5;

    sdcb->sdfunc->port_init(1);

    if (!sdcb->card.flag_sdhc) {
        addr <<= 9;
    }

    while (1) {
        if (sdcb->card.abend) {
            return;
        }
        if (sd_read_multiple_block(sdcb, addr)) {
            TRACE("READ BLK OK\n");
            return;
        }
        if (--retry_times == 0) {
            sdcb->card.abend = 1;
            return;
        }
        //TRACE("retry\n");
    }
}

//SD卡发送读命令并KICK
AT(.text.sdread)
void sd_read_start(sdcb_t *sdcb, void *buf, u32 lba)
{
    sdcb->sdfunc->port_init(1);
    if (sdcb->card.rw_sta == RW_READ) {
        if (sdcb->card.rw_lba == lba) {
            sdio_read_data(buf, 512);
        } else {
            sd_stop(sdcb, 0);                      //读不连续地址，STOP上一次读
            sdio_read_data(buf, 512);
            sd_read_send_cmd(sdcb, lba);        //发送读命令
        }
    } else {
        if (sdcb->card.rw_sta == RW_WRITE) {
            sd_stop(sdcb, 0);                      //STOP上一次写
        }
        sdio_read_data(buf, 512);
        sd_read_send_cmd(sdcb, lba);            //发送读命令
    }
    sdcb->card.rw_sta = RW_READ;
    sdcb->card.rw_lba = lba + 1;                //下一次连续读的地址
}

//SD读接口
AT(.text.sdread)
bool sd_read_try(sdcb_t *sdcb, void *buf, u32 lba)
{
    TRACE("read: %08x\n", lba);

    if ((sdcb->card.sta == DEV_STA_NEW) || (sdcb->card.sta == DEV_STA_INVALID)) {
        sd_init(sdcb);
    }
    if (sdcb->card.sta != DEV_STA_OK) {
        return false;
    }
    if (sdcb->card.abend) {
        return false;
    }
    if (sdcb->card.capacity < lba) {
       lba = sdcb->card.capacity - 1;           //超过容量，读取最后一包
    }
    sd_read_start(sdcb, buf, lba);
    return sdcb->sdfunc->read_wait(sdcb);
}

//SD读接口，包括重试
AT(.text.sdread)
bool sd_read(sdcb_t *sdcb, void *buf, u32 lba)
{
    u8 init_retry = sdcb->sdcfg->rw_init_retry;
    while(init_retry--) {   //DEV_STA_INVALID, 读失败后, 尝试重新初始化SD卡, 再进行读.
        uint retry = sdcb->sdcfg->rw_retry;
        while (retry--) {
            sdcb->sdfunc->port_init(1);
            if (sd_read_try(sdcb, buf, lba)) {
                if (sdcb->sdcfg->rw_need_stop & BIT(0)) {
                    sd_stop(sdcb, 0);       //每次读完stop一下
                }
                sdcb->sdfunc->port_init(3);
                return true;
            }
        }
        sdcb->sdfunc->port_init(2);
        sdcb->card.sta = DEV_STA_INVALID; //DEV_STA_INVALID, 读失败后, 尝试重新初始化SD卡, 再进行读.

        if (!sdcb->card.online) {  //卡不在线直接退出.
            break;
        }
        delay_5ms(4);
    }
    return false;
}

//SD发送写命令接口
AT(.text.sdwrite)
void sd_write_send_cmd(sdcb_t *sdcb, u32 lba)
{
    u32 addr = lba;

    sdcb->sdfunc->port_init(1);

    if (!sdcb->card.flag_sdhc) {
        addr <<= 9;
    }
    sd_write_multiple_block(sdcb, addr);
}

//SD发送写命令并进行KICK
AT(.text.sdwrite)
void sd_write_start(sdcb_t *sdcb, void* buf, u32 lba)
{
    sdcb->sdfunc->port_init(1);
    if (sdcb->card.rw_sta == RW_WRITE) {
        if (sdcb->card.rw_lba != lba) {
            sd_stop(sdcb, 0);                      //写不连续地址，STOP上一次写
            sd_write_send_cmd(sdcb, lba);          //发送写命令
        }
    } else {
        if (sdcb->card.rw_sta == RW_READ) {
            sd_stop(sdcb, 0);                      //STOP上一次读
        }
        sd_write_send_cmd(sdcb, lba);              //发送写命令
    }
    sdio_write_data(buf, 512);                     //KICK BUF地址
    sdcb->card.rw_sta = RW_WRITE;
    sdcb->card.rw_lba = lba + 1;
}

//写SD卡
AT(.text.sdwrite)
bool sd_write_try(sdcb_t *sdcb, void* buf, u32 lba)
{
    TRACE("write: %08x\n", lba);
    if ((sdcb->card.sta == DEV_STA_NEW) || (sdcb->card.sta == DEV_STA_INVALID)) {
        sd_init(sdcb);
    }
    if (sdcb->card.sta != DEV_STA_OK) {
        return 0;
    }
    if (sdcb->card.abend) {
        return false;
    }
    sd_write_start(sdcb, buf, lba);
    return sdcb->sdfunc->write_wait(sdcb);
}

//写SD卡，包含重试
AT(.text.sdwrite)
bool sd_write(sdcb_t *sdcb, void* buf, u32 lba)
{
    u8 retry = sdcb->sdcfg->rw_retry;
    while (retry--) {
        sdcb->sdfunc->port_init(1);
        if (sd_write_try(sdcb, buf, lba)) {
            sdcb->sdfunc->port_init(3);
            return true;
        }
        TRACE("sd_write retry\n");
        if (sdcb->sdcfg->rw_need_stop & BIT(1)) {
            sd_stop(sdcb, 1);
        }
    }
    sdcb->sdfunc->port_init(2);
    sdcb->card.sta = DEV_STA_INVALID;
    return false;
}

//SD卡读写停止接口
AT(.text.sdread)
bool sd_stop(sdcb_t *sdcb, bool type)
{
    bool res = false;
    if (sdcb->card.sta != DEV_STA_OK) {
        return false;
    }
    if (sdcb->card.rw_sta == RW_IDLE) {
        return true;
    }
    sdcb->sdfunc->port_init(1);
    sdcb->card.rw_sta = RW_IDLE;

    uint retry = sdcb->sdcfg->stop_retry;
    while (1) {
        if (sdcb->card.abend) {
            break;
        }
        sd_stop_transmission(sdcb);
        delay_us(20);
        sd_send_status(sdcb);
        if ((sdio_get_response(SDIO_RESP1) & 0x1e00) == 0x0800) {
            res = true;
            break;
        }
        if (--retry == 0) {
            sdcb->card.abend = 1;
            break;
        }
        delay_us(20);
    }

    if (type) {
        sdcb->sdfunc->port_init(2);
    }
    return res;
}

AT(.text.sdcid)
u32 get_sd_cid_flag(void)
{
    return cid_flag;
}

///////////////////////下面是fs用到函数////////////
sdcb_t *fs_sdcb;

void sd_set_fs_sdcb_addr( sdcb_t* ptr)
{
    fs_sdcb = ptr;
}

u8 sd_is_online(void)
{
    return fs_sdcb->card.online;
}

void sd0_go_idle_state(void)
{
    sd_go_idle_state(fs_sdcb);
}
//将SD状态设置为INVALID
void sd0_set_invalid_state(void)
{
	if(fs_sdcb->card.sta == DEV_STA_OK){
		sd0_go_idle_state();
		fs_sdcb->card.sta = DEV_STA_INVALID;
	}
}

AT(.com_text.detect)
u8 get_usbtf_muxio(void)
{
    return 0;
}

bool sd0_init(void)
{
    return sd_init(fs_sdcb);
}

bool sd0_stop(bool type)
{
    return sd_stop(fs_sdcb, type);
}

bool sd0_read(void *buf, u32 lba)
{
    return sd_read(fs_sdcb, buf, lba);
}


bool sd0_write(void* buf, u32 lba)
{
    return sd_write(fs_sdcb, buf, lba);
}

void sd0_write_start(void *buf, u32 lba)
{
    return sd_write_start(fs_sdcb, buf, lba);
}

void sd0_write_kick(void *buf)
{
    sdio_write_kick(fs_sdcb, buf);
}

bool sd0_write_wait(void)
{
    return sd_write_wait(fs_sdcb);
}

AT(.com_text.usb.api)
void os_sem_uhs_trytake(void)
{

}

void sd_disk_switch(u8 index)
{
}

AT(.com_text.usb.api)
bool uhs_wait_pending(uint timeout)
{
    return true;
}
