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
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;
|
||
|
}
|