Пример #1
0
uint8_t devsd_transfer_sector1(void)
{
    uint8_t attempt;
    bool success;

    sd_drive = blk_op.blkdev->driver_data & DRIVE_NR_MASK;

    for(attempt=0; attempt<8; attempt++){
	if(sd_send_command(blk_op.is_read ? CMD17 : CMD24, 
                    /* for byte addressed cards, shift LBA to convert to byte address */
                    (blk_op.blkdev->driver_data & CT_BLOCK) ? blk_op.lba : (blk_op.lba << 9)
                    ) == 0){
	    if(blk_op.is_read){
                success = (sd_spi_wait(false) == 0xFE);
                if(success){
                    sd_spi_receive_sector();
					//sd_spi_wait(false);
				}
            }else{
                success = false;
                if(sd_spi_wait(true) == 0xFF){
                    sd_spi_transmit_byte(0xFE);
                    sd_spi_transmit_sector();
                    sd_spi_transmit_byte(0xFF); /* dummy CRC */
                    sd_spi_transmit_byte(0xFF);
                    success = ((sd_spi_wait(false) & 0x1F) == 0x05);
                }
            }
	}else
	    success = false;

	sd_spi_release();

	if(success)
	    return 1;

	kputs("sd: failed, retrying.\n");
    }

    udata.u_error = EIO;
    return 0;
}
Пример #2
0
int sd_send_command(unsigned char cmd, uint32_t arg)
{
    unsigned char n, res, *p;

    if (cmd & 0x80) {   /* ACMD<n> is the command sequense of CMD55-CMD<n> */
        cmd &= 0x7F;
        res = sd_send_command(CMD55, 0);
        if (res > 1)
            return res;
    }

    /* Select the card and wait for ready */
    sd_spi_release(); /* raise CS, then sends 8 clocks (some cards require this) */
    sd_spi_lower_cs();
    if(sd_spi_wait(true) != 0xFF)
        return 0xFF;

    /* Send command packet */
    sd_spi_transmit_byte(cmd);                        /* Start + Command index */
#if 0
    sd_spi_transmit_byte((unsigned char)(arg >> 24)); /* Argument[31..24] */
    sd_spi_transmit_byte((unsigned char)(arg >> 16)); /* Argument[23..16] */
    sd_spi_transmit_byte((unsigned char)(arg >> 8));  /* Argument[15..8] */
    sd_spi_transmit_byte((unsigned char)arg);         /* Argument[7..0] */
#else
    /* sdcc sadly unable to figure this out for itself yet */
    p = ((unsigned char *)&arg)+3;
    sd_spi_transmit_byte(*(p--));                     /* Argument[31..24] */
    sd_spi_transmit_byte(*(p--));                     /* Argument[23..16] */
    sd_spi_transmit_byte(*(p--));                     /* Argument[15..8] */
    sd_spi_transmit_byte(*p);                         /* Argument[7..0] */
#endif
    /* there's only a few commands (in native mode) that need correct CRCs */
    n = 0x01;                                                /* Dummy CRC + Stop */
    if (cmd == CMD0) n = 0x95;                               /* Valid CRC for CMD0(0) */
    if (cmd == CMD8) n = 0x87;                               /* Valid CRC for CMD8(0x1AA) */
    sd_spi_transmit_byte(n);

    /* Receive command response */
    if (cmd == CMD12)
        sd_spi_receive_byte();     /* Skip a stuff byte when stop reading */
    n = 20;                             /* Wait for a valid response */
    do {
        res = sd_spi_receive_byte();
    } while ((res & 0x80) && --n);

    return res;         /* Return with the response value */
}