⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
        printf("SD: GEN_CMD 0x%08x\n", req.arg);        switch (sd->state) {        case sd_transfer_state:            sd->data_offset = 0;            if (req.arg & 1)                sd->state = sd_sendingdata_state;            else                sd->state = sd_receivingdata_state;            return sd_r1;        default:            break;        }        break;    default:    bad_cmd:        sd->card_status |= ILLEGAL_COMMAND;        printf("SD: Unknown CMD%i\n", req.cmd);        return sd_r0;    unimplemented_cmd:        /* Commands that are recognised but not yet implemented in SPI mode.  */        sd->card_status |= ILLEGAL_COMMAND;        printf ("SD: CMD%i not implemented in SPI mode\n", req.cmd);        return sd_r0;    }    sd->card_status |= ILLEGAL_COMMAND;    printf("SD: CMD%i in a wrong state\n", req.cmd);    return sd_r0;}static sd_rsp_type_t sd_app_command(SDState *sd,                                    struct sd_request_s req) {    uint32_t rca;    if (sd_cmd_type[req.cmd] == sd_ac || sd_cmd_type[req.cmd] == sd_adtc)        rca = req.arg >> 16;    DPRINTF("ACMD%d 0x%08x\n", req.cmd, req.arg);    switch (req.cmd) {    case 6:	/* ACMD6:  SET_BUS_WIDTH */        switch (sd->state) {        case sd_transfer_state:            sd->sd_status[0] &= 0x3f;            sd->sd_status[0] |= (req.arg & 0x03) << 6;            return sd_r1;        default:            break;        }        break;    case 13:	/* ACMD13: SD_STATUS */        switch (sd->state) {        case sd_transfer_state:            sd->data_start = 0;            sd->data_offset = 0;            return sd_r1;        default:            break;        }        break;    case 22:	/* ACMD22: SEND_NUM_WR_BLOCKS */        switch (sd->state) {        case sd_transfer_state:            *(uint32_t *) sd->data = sd->blk_written;            sd->data_start = 0;            sd->data_offset = 0;            return sd_r1;        default:            break;        }        break;    case 23:	/* ACMD23: SET_WR_BLK_ERASE_COUNT */        switch (sd->state) {        case sd_transfer_state:            return sd_r1;        default:            break;        }        break;    case 41:	/* ACMD41: SD_APP_OP_COND */        if (sd->spi) {            /* SEND_OP_CMD */            sd->state = sd_transfer_state;            return sd_r1;        }        switch (sd->state) {        case sd_idle_state:            /* We accept any voltage.  10000 V is nothing.  */            if (req.arg)                sd->state = sd_ready_state;            return sd_r3;        default:            break;        }        break;    case 42:	/* ACMD42: SET_CLR_CARD_DETECT */        switch (sd->state) {        case sd_transfer_state:            /* Bringing in the 50KOhm pull-up resistor... Done.  */            return sd_r1;        default:            break;        }        break;    case 51:	/* ACMD51: SEND_SCR */        switch (sd->state) {        case sd_transfer_state:            sd->state = sd_sendingdata_state;            sd->data_start = 0;            sd->data_offset = 0;            return sd_r1;        default:            break;        }        break;    default:        /* Fall back to standard commands.  */        sd->card_status &= ~APP_CMD;        return sd_normal_command(sd, req);    }    printf("SD: ACMD%i in a wrong state\n", req.cmd);    return sd_r0;}int sd_do_command(SDState *sd, struct sd_request_s *req,                  uint8_t *response) {    uint32_t last_status = sd->card_status;    sd_rsp_type_t rtype;    int rsplen;    if (!bdrv_is_inserted(sd->bdrv)) {        return 0;    }    if (sd_req_crc_validate(req)) {        sd->card_status &= ~COM_CRC_ERROR;        return 0;    }    sd->card_status &= ~CARD_STATUS_B;    sd_set_status(sd);    if (last_status & CARD_IS_LOCKED)        if (((last_status & APP_CMD) &&                                 req->cmd == 41) ||                        (!(last_status & APP_CMD) &&                         (sd_cmd_class[req->cmd] == 0 ||                          sd_cmd_class[req->cmd] == 7 ||                          req->cmd == 16 || req->cmd == 55))) {            sd->card_status |= ILLEGAL_COMMAND;            printf("SD: Card is locked\n");            return 0;        }    if (last_status & APP_CMD) {        rtype = sd_app_command(sd, *req);        sd->card_status &= ~APP_CMD;    } else        rtype = sd_normal_command(sd, *req);    sd->current_cmd = req->cmd;    switch (rtype) {    case sd_r1:    case sd_r1b:        sd_response_r1_make(sd, response, last_status);        rsplen = 4;        break;    case sd_r2_i:        memcpy(response, sd->cid, sizeof(sd->cid));        rsplen = 16;        break;    case sd_r2_s:        memcpy(response, sd->csd, sizeof(sd->csd));        rsplen = 16;        break;    case sd_r3:        sd_response_r3_make(sd, response);        rsplen = 4;        break;    case sd_r6:        sd_response_r6_make(sd, response);        rsplen = 4;        break;    case sd_r7:        sd_response_r7_make(sd, response);        rsplen = 4;        break;    case sd_r0:    default:        rsplen = 0;        break;    }    if (sd->card_status & ILLEGAL_COMMAND)        rsplen = 0;#ifdef DEBUG_SD    if (rsplen) {        int i;        DPRINTF("Response:");        for (i = 0; i < rsplen; i++)            printf(" %02x", response[i]);        printf(" state %d\n", sd->state);    } else {        DPRINTF("No response %d\n", sd->state);    }#endif    return rsplen;}/* No real need for 64 bit addresses here */static void sd_blk_read(SDState *sd, uint32_t addr, uint32_t len){    uint32_t end = addr + len;    if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {        printf("sd_blk_read: read error on host side\n");        return;    }    if (end > (addr & ~511) + 512) {        memcpy(sd->data, sd->buf + (addr & 511), 512 - (addr & 511));        if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) {            printf("sd_blk_read: read error on host side\n");            return;        }        memcpy(sd->data + 512 - (addr & 511), sd->buf, end & 511);    } else        memcpy(sd->data, sd->buf + (addr & 511), len);}static void sd_blk_write(SDState *sd, uint32_t addr, uint32_t len){    uint32_t end = addr + len;    if ((addr & 511) || len < 512)        if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {            printf("sd_blk_write: read error on host side\n");            return;        }    if (end > (addr & ~511) + 512) {        memcpy(sd->buf + (addr & 511), sd->data, 512 - (addr & 511));        if (bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {            printf("sd_blk_write: write error on host side\n");            return;        }        if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) {            printf("sd_blk_write: read error on host side\n");            return;        }        memcpy(sd->buf, sd->data + 512 - (addr & 511), end & 511);        if (bdrv_write(sd->bdrv, end >> 9, sd->buf, 1) == -1)            printf("sd_blk_write: write error on host side\n");    } else {        memcpy(sd->buf + (addr & 511), sd->data, len);        if (!sd->bdrv || bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1)            printf("sd_blk_write: write error on host side\n");    }}#define BLK_READ_BLOCK(a, len)	sd_blk_read(sd, a, len)#define BLK_WRITE_BLOCK(a, len)	sd_blk_write(sd, a, len)#define APP_READ_BLOCK(a, len)	memset(sd->data, 0xec, len)#define APP_WRITE_BLOCK(a, len)void sd_write_data(SDState *sd, uint8_t value){    int i;    if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv))        return;    if (sd->state != sd_receivingdata_state) {        printf("sd_write_data: not in Receiving-Data state\n");        return;    }    if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))        return;    switch (sd->current_cmd) {    case 24:	/* CMD24:  WRITE_SINGLE_BLOCK */        sd->data[sd->data_offset ++] = value;        if (sd->data_offset >= sd->blk_len) {            /* TODO: Check CRC before committing */            sd->state = sd_programming_state;            BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);            sd->blk_written ++;            sd->csd[14] |= 0x40;            /* Bzzzzzzztt .... Operation complete.  */            sd->state = sd_transfer_state;        }        break;    case 25:	/* CMD25:  WRITE_MULTIPLE_BLOCK */        sd->data[sd->data_offset ++] = value;        if (sd->data_offset >= sd->blk_len) {            /* TODO: Check CRC before committing */            sd->state = sd_programming_state;            BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);            sd->blk_written ++;            sd->data_start += sd->blk_len;            sd->data_offset = 0;            if (sd->data_start + sd->blk_len > sd->size) {                sd->card_status |= ADDRESS_ERROR;                break;            }            if (sd_wp_addr(sd, sd->data_start)) {                sd->card_status |= WP_VIOLATION;                break;            }            sd->csd[14] |= 0x40;            /* Bzzzzzzztt .... Operation complete.  */            sd->state = sd_receivingdata_state;        }        break;    case 26:	/* CMD26:  PROGRAM_CID */        sd->data[sd->data_offset ++] = value;        if (sd->data_offset >= sizeof(sd->cid)) {            /* TODO: Check CRC before committing */            sd->state = sd_programming_state;            for (i = 0; i < sizeof(sd->cid); i ++)                if ((sd->cid[i] | 0x00) != sd->data[i])                    sd->card_status |= CID_CSD_OVERWRITE;            if (!(sd->card_status & CID_CSD_OVERWRITE))                for (i = 0; i < sizeof(sd->cid); i ++) {                    sd->cid[i] |= 0x00;                    sd->cid[i] &= sd->data[i];                }            /* Bzzzzzzztt .... Operation complete.  */            sd->state = sd_transfer_state;        }        break;    case 27:	/* CMD27:  PROGRAM_CSD */        sd->data[sd->data_offset ++] = value;        if (sd->data_offset >= sizeof(sd->csd)) {            /* TODO: Check CRC before committing */            sd->state = sd_programming_state;            for (i = 0; i < sizeof(sd->csd); i ++)                if ((sd->csd[i] | sd_csd_rw_mask[i]) !=                    (sd->data[i] | sd_csd_rw_mask[i]))                    sd->card_status |= CID_CSD_OVERWRITE;            /* Copy flag (OTP) & Permanent write protect */            if (sd->csd[14] & ~sd->data[14] & 0x60)                sd->card_status |= CID_CSD_OVERWRITE;            if (!(sd->card_status & CID_CSD_OVERWRITE))                for (i = 0; i < sizeof(sd->csd); i ++) {                    sd->csd[i] |= sd_csd_rw_mask[i];                    sd->csd[i] &= sd->data[i];                }            /* Bzzzzzzztt .... Operation complete.  */            sd->state = sd_transfer_state;        }        break;    case 42:	/* CMD42:  LOCK_UNLOCK */        sd->data[sd->data_offset ++] = value;        if (sd->data_offset >= sd->blk_len) {            /* TODO: Check CRC before committing */            sd->state = sd_programming_state;            sd_lock_command(sd);            /* Bzzzzzzztt .... Operation complete.  */            sd->state = sd_transfer_state;        }        break;    case 56:	/* CMD56:  GEN_CMD */        sd->data[sd->data_offset ++] = value;        if (sd->data_offset >= sd->blk_len) {            APP_WRITE_BLOCK(sd->data_start, sd->data_offset);            sd->state = sd_transfer_state;        }        break;    default:        printf("sd_write_data: unknown command\n");        break;    }}uint8_t sd_read_data(SDState *sd){    /* TODO: Append CRCs */    uint8_t ret;    if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv))        return 0x00;    if (sd->state != sd_sendingdata_state) {        printf("sd_read_data: not in Sending-Data state\n");        return 0x00;    }    if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))        return 0x00;    switch (sd->current_cmd) {    case 6:	/* CMD6:   SWITCH_FUNCTION */        ret = sd->data[sd->data_offset ++];        if (sd->data_offset >= 64)            sd->state = sd_transfer_state;        break;    case 9:	/* CMD9:   SEND_CSD */    case 10:	/* CMD10:  SEND_CID */        ret = sd->data[sd->data_offset ++];        if (sd->data_offset >= 16)            sd->state = sd_transfer_state;        break;    case 11:	/* CMD11:  READ_DAT_UNTIL_STOP */        if (sd->data_offset == 0)            BLK_READ_BLOCK(sd->data_start, sd->blk_len);        ret = sd->data[sd->data_offset ++];        if (sd->data_offset >= sd->blk_len) {            sd->data_start += sd->blk_len;            sd->data_offset = 0;            if (sd->data_start + sd->blk_len > sd->size) {                sd->card_status |= ADDRESS_ERROR;                break;            }        }        break;    case 13:	/* ACMD13: SD_STATUS */        ret = sd->sd_status[sd->data_offset ++];        if (sd->data_offset >= sizeof(sd->sd_status))            sd->state = sd_transfer_state;        break;    case 17:	/* CMD17:  READ_SINGLE_BLOCK */        if (sd->data_offset == 0)            BLK_READ_BLOCK(sd->data_start, sd->blk_len);        ret = sd->data[sd->data_offset ++];        if (sd->data_offset >= sd->blk_len)            sd->state = sd_transfer_state;        break;    case 18:	/* CMD18:  READ_MULTIPLE_BLOCK */        if (sd->data_offset == 0)            BLK_READ_BLOCK(sd->data_start, sd->blk_len);        ret = sd->data[sd->data_offset ++];        if (sd->data_offset >= sd->blk_len) {            sd->data_start += sd->blk_len;            sd->data_offset = 0;            if (sd->data_start + sd->blk_len > sd->size) {                sd->card_status |= ADDRESS_ERROR;                break;            }        }        break;    case 22:	/* ACMD22: SEND_NUM_WR_BLOCKS */        ret = sd->data[sd->data_offset ++];        if (sd->data_offset >= 4)            sd->state = sd_transfer_state;        break;    case 30:	/* CMD30:  SEND_WRITE_PROT */        ret = sd->data[sd->data_offset ++];        if (sd->data_offset >= 4)            sd->state = sd_transfer_state;        break;    case 51:	/* ACMD51: SEND_SCR */        ret = sd->scr[sd->data_offset ++];        if (sd->data_offset >= sizeof(sd->scr))            sd->state = sd_transfer_state;        break;    case 56:	/* CMD56:  GEN_CMD */        if (sd->data_offset == 0)            APP_READ_BLOCK(sd->data_start, sd->blk_len);        ret = sd->data[sd->data_offset ++];        if (sd->data_offset >= sd->blk_len)            sd->state = sd_transfer_state;        break;    default:        printf("sd_read_data: unknown command\n");        return 0x00;    }    return ret;}int sd_data_ready(SDState *sd){    return sd->state == sd_sendingdata_state;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -