Example #1
0
static uint8 send_slow_cmd (
	uint8 cmd,		/* Command byte */
	uint32 arg		/* Argument */
)
{
	uint8 n, res;
	uint8 cb[6];
	int i;

	(void)spi_slow_sr_byte(0xff);
	i = 0;
	
	do {
		
		res = spi_slow_sr_byte(0xff);
		i++;
		
	} while ((res != 0xFF) && i < 100000);
	
	if (res != 0xff) {
#ifdef SD_DEBUG
		dbglog(DBG_DEBUG, "%s: CMD 0x%02x error\n", __func__, cmd);
#endif
		return(0xff);
	}

	cb[0] = cmd;
	cb[1] = (uint8)(arg >> 24);
	cb[2] = (uint8)(arg >> 16);
	cb[3] = (uint8)(arg >> 8);
	cb[4] = (uint8)arg;
	cb[5] = sd_crc7(cb, 5, 0);
	/* Send command packet */
	spi_slow_sr_byte(cmd);		/* Command */
	spi_slow_sr_byte(cb[1]);		/* Argument[31..24] */
	spi_slow_sr_byte(cb[2]);		/* Argument[23..16] */
	spi_slow_sr_byte(cb[3]);		/* Argument[15..8] */
	spi_slow_sr_byte(cb[4]);		/* Argument[7..0] */
	spi_slow_sr_byte(cb[5]);		// CRC7

	/* Receive command response */
	if (cmd == CMD12) 
		(void)spi_slow_sr_byte(0xff);/* Skip a stuff byte when stop reading */
		
	n = 20; /* Wait for a valid response in timeout of 10 attempts */
	
	do {
		res = spi_slow_sr_byte(0xff);
	} while ((res & 0x80) && --n);
	
#ifdef SD_DEBUG
	dbglog(DBG_DEBUG, "%s: CMD 0x%02x response 0x%02x\n", __func__, cmd, res);
#endif
	
	return res; /* Return with the response value */
}
/**
 * \ingroup sd_raw
 * Send a command to the memory card which responses with a R1 response (and possibly others).
 *
 * \param[in] command The command to send.
 * \param[in] arg The argument for command.
 * \returns The command answer.
 */
uint8_t sd_raw_send_command(uint8_t command, uint32_t arg)
{
    uint8_t response;
    uint8_t *args = reinterpret_cast<uint8_t *>(&arg);

    /* wait some clock cycles */
    sd_raw_rec_byte();

#if !SD_RAW_SAVE_RAM
    if ( sd_use_crc ) {
	uint8_t crc[6] = { command | 0x40, args[3], args[2], args[1], args[0] };
	crc[5] = sd_crc7(crc, 5);
	for (uint8_t i = 0; i < 6; i++)
	    sd_raw_send_byte(crc[i]);
    }
    else {
#endif
	/* send command via SPI */
	sd_raw_send_byte(0x40 | command);
	for (int8_t i = 3; i >= 0; i--)
	    sd_raw_send_byte(args[i]);

	switch(command)
	{
        case CMD_GO_IDLE_STATE:
	    sd_raw_send_byte(0x95);
	    break;
        case CMD_SEND_IF_COND:
	    sd_raw_send_byte(0x87);
	    break;
        default:
	    sd_raw_send_byte(0xff);
	    break;
	}
#if !SD_RAW_SAVE_RAM
    }
#endif

    /* receive response */
    for(uint8_t i = 0; i < 10; ++i)
    {
        response = sd_raw_rec_byte();
        if(response != 0xff)
            break;
    }

    return response;
}