You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.0 KiB
C

4 years ago
#include "sd_mmc_spi.h"
#include "assert.h"
static sd_mmc_spi_errno_t sd_mmc_spi_err;
static uint8_t spi_m_sync_crc7(uint8_t * buf, uint8_t size)
{
uint8_t crc, value, i;
crc = 0;
while (size--) {
value = *buf++;
for (i = 0; i < 8; i++) {
crc <<= 1;
if ((value & 0x80) ^ (crc & 0x80)) {
crc ^= 0x09;
}
value <<= 1;
}
}
crc = (crc << 1) | 1;
return crc;
}
bool spi_m_sync_send_cmd(struct spi_m_sync_descriptor* spi, uint32_t cmd,
uint32_t arg)
{
return spi_m_sync_adtc_start(spi, cmd, arg, 0, 0, false);
}
bool spi_m_sync_adtc_start(struct spi_m_sync_descriptor* spi,
uint32_t cmd, uint32_t arg, uint16_t block_size,
uint16_t nb_block, bool access_block)
{
uint8_t dummy = 0xFF;
uint8_t cmd_token[6];
uint8_t ncr_timeout;
uint8_t r1;
uint16_t dummy2 = 0xFF;
(void)access_block;
assert(cmd & SDMMC_RESP_PRESENT);
sd_mmc_spi_err = SD_MMC_SPI_NO_ERR;
cmd_token[0] = SPI_CMD_ENCODE(SDMMC_CMD_GET_INDEX(cmd));
cmd_token[1] = arg >> 24;
cmd_token[2] = arg >> 16;
cmd_token[3] = arg >> 8;
cmd_token[4] = arg;
cmd_token[5] = spi_m_sync_crc7(cmd_token, 5);
// 8 cycles to respect Ncs timing
spi_m_sync_io_write(spi, &dummy, 1);
// send command
spi_m_sync_io_write(spi, cmd_token, sizeof(cmd_token));
// Wait for response
// Two retries will be done to manage the Ncr timing between command and response
// Ncr: Min. 1x8 clock cycle, Max 8x8 clock cycles
// WORKAROUND for no compliance (Atmel Internal ref. SD13)
r1 = 0xFF;
// Ignore first byte because Ncr min. = 8 clock cycles
spi_m_sync_io_write(spi, &dummy, 1);
spi_m_sync_io_read(spi, &r1, 1);
ncr_timeout = 7;
while(1)
{
spi_m_sync_io_write(spi, &dummy, 1);
spi_m_sync_io_read(spi, &r1, 1);
if((r1 & R1_SPI_ERROR) == 0)
{
// Valid response
break;
}
if(--ncr_timeout == 0)
{
}
}
return true;
}
bool spi_m_sync_start_read_blocks(struct spi_m_sync_descriptor* spi,
void *dst, uint16_t nb_block)
{
return true;
}
bool spi_m_sync_start_write_blocks(struct spi_m_sync_descriptor* spi,
const void *src, uint16_t nb_block)
{
return true;
}
bool spi_m_sync_wait_end_of_write_blocks(struct spi_m_sync_descriptor* spi)
{
return true;
}
bool spi_m_sync_wait_end_of_read_blocks(struct spi_m_sync_descriptor* spi)
{
return true;
}
bool spi_m_sync_write_word(struct spi_m_sync_descriptor* spi,
uint32_t value)
{
return true;
}
bool spi_m_sync_read_word(struct spi_m_sync_descriptor* spi, uint32_t* value)
{
return true;
}
uint32_t spi_m_sync_get_response(struct spi_m_sync_descriptor* spi)
{
return 0;
}
void spi_m_sync_send_clock(struct spi_m_sync_descriptor* spi) {}
int32_t spi_m_sync_select_device(struct spi_m_sync_descriptor* spi, uint8_t slot, uint32_t clock, uint8_t bus_width, bool high_speed)
{
return 0;
}
int32_t spi_m_sync_deselect_device(struct spi_m_sync_descriptor* spi, uint8_t slot)
{
return 0;
}