X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fdrivers%2Fao_sdcard.c;h=952000a71f8000709f6f1a1643d92ab3eff769fd;hb=7afcec1a1dce140dfa569469df4ef42ed407a742;hp=2174af1e546572ca55a1e08562ed8301426233fa;hpb=e14834817f78a04b4d9b44a8373119dffd42c966;p=fw%2Faltos diff --git a/src/drivers/ao_sdcard.c b/src/drivers/ao_sdcard.c index 2174af1e..952000a7 100644 --- a/src/drivers/ao_sdcard.c +++ b/src/drivers/ao_sdcard.c @@ -27,6 +27,11 @@ #define ao_sdcard_select() ao_gpio_set(AO_SDCARD_SPI_CS_PORT,AO_SDCARD_SPI_CS_PIN,AO_SDCARD_SPI_CS,0) #define ao_sdcard_deselect() ao_gpio_set(AO_SDCARD_SPI_CS_PORT,AO_SDCARD_SPI_CS_PIN,AO_SDCARD_SPI_CS,1) +/* Include SD card commands */ +#define SDCARD_DEBUG 0 + +/* Spew SD tracing */ +#define SDCARD_TRACE 0 static uint8_t initialized; static uint8_t present; @@ -36,7 +41,7 @@ static enum ao_sdtype sdtype; #define ao_sdcard_lock() ao_mutex_get(&mutex) #define ao_sdcard_unlock() ao_mutex_put(&mutex) -#if 0 +#if SDCARD_TRACE #define DBG(...) printf(__VA_ARGS__) #else #define DBG(...) @@ -170,6 +175,20 @@ ao_sdcard_send_if_cond(uint32_t arg, uint8_t send_if_cond_response[4]) return ret; } +static uint8_t +ao_sdcard_send_status(void) +{ + uint8_t ret; + + DBG ("send_status\n"); + ao_sdcard_select(); + ret = ao_sdcard_send_cmd(SDCARD_SEND_STATUS, 0); + ao_sdcard_recv_reply(NULL, 0); + if (ret != SDCARD_STATUS_READY_STATE) + DBG ("\tsend_if_cond failed %02x\n", ret); + return ret; +} + static uint8_t ao_sdcard_set_blocklen(uint32_t blocklen) { @@ -182,7 +201,6 @@ ao_sdcard_set_blocklen(uint32_t blocklen) if (ret != SDCARD_STATUS_READY_STATE) DBG ("\tsend_if_cond failed %02x\n", ret); return ret; - } static uint8_t @@ -355,6 +373,7 @@ ao_sdcard_read_block(uint32_t block, uint8_t *data) ao_sdcard_unlock(); return 0; } + DBG("read block %d\n", block); if (sdtype != ao_sdtype_sd2block) block <<= 9; ao_sdcard_get(); @@ -364,7 +383,8 @@ ao_sdcard_read_block(uint32_t block, uint8_t *data) if (ret != SDCARD_STATUS_READY_STATE) goto bail; - if (ao_sdcard_wait_block_start() != 0xfe) { + /* Wait for the data start block marker */ + if (ao_sdcard_wait_block_start() != SDCARD_DATA_START_BLOCK) { ret = 0x3f; goto bail; } @@ -375,6 +395,7 @@ bail: ao_sdcard_deselect(); ao_sdcard_put(); ao_sdcard_unlock(); + DBG("read %s\n", ret == SDCARD_STATUS_READY_STATE ? "success" : "failure"); return ret == SDCARD_STATUS_READY_STATE; } @@ -384,15 +405,112 @@ bail: uint8_t ao_sdcard_write_block(uint32_t block, uint8_t *data) { - /* Not doing anything until the file system code seems reasonable - */ - return 1; + uint8_t ret; + uint8_t response; + uint8_t start_block[2]; + int i; + + ao_sdcard_lock(); + if (!initialized) { + ao_sdcard_setup(); + initialized = 1; + if (sdtype != ao_sdtype_unknown) + present = 1; + } + if (!present) { + ao_sdcard_unlock(); + return 0; + } + DBG("write block %d\n", block); + if (sdtype != ao_sdtype_sd2block) + block <<= 9; + ao_sdcard_get(); + ao_sdcard_select(); + + ret = ao_sdcard_send_cmd(SDCARD_WRITE_BLOCK, block); + ao_sdcard_recv_reply(NULL, 0); + if (ret != SDCARD_STATUS_READY_STATE) + goto bail; + + /* Write a pad byte followed by the data start block marker */ + start_block[0] = 0xff; + start_block[1] = SDCARD_DATA_START_BLOCK; + ao_sdcard_send(start_block, 2); + + /* Send the data */ + ao_sdcard_send(data, 512); + + /* Fake the CRC */ + ao_sdcard_send_fixed(0xff, 2); + + /* See if the card liked the data */ + ao_sdcard_recv(&response, 1); + if ((response & SDCARD_DATA_RES_MASK) != SDCARD_DATA_RES_ACCEPTED) { + ret = 0x3f; + goto bail; + } + + /* Wait for the bus to go idle (should be done with an interrupt) */ + for (i = 0; i < SDCARD_IDLE_TIMEOUT; i++) { + ao_sdcard_recv(&response, 1); + if (response == 0xff) + break; + } + if (i == SDCARD_IDLE_TIMEOUT) + ret = 0x3f; +bail: + ao_sdcard_deselect(); + ao_sdcard_put(); + ao_sdcard_unlock(); + DBG("write %s\n", ret == SDCARD_STATUS_READY_STATE ? "success" : "failure"); + return ret == SDCARD_STATUS_READY_STATE; } +#if SDCARD_DEBUG +static uint8_t test_data[512]; + +static void +ao_sdcard_test_read(void) +{ + int i; + if (!ao_sdcard_read_block(1, test_data)) { + printf ("read error\n"); + return; + } + printf ("data:"); + for (i = 0; i < 18; i++) + printf (" %02x", test_data[i]); + printf ("\n"); +} + +static void +ao_sdcard_test_write(void) +{ + int i; + printf ("data:"); + for (i = 0; i < 16; i++) { + test_data[i]++; + printf (" %02x", test_data[i]); + } + printf ("\n"); + if (!ao_sdcard_write_block(1, test_data)) { + printf ("write error\n"); + return; + } +} + +static const struct ao_cmds ao_sdcard_cmds[] = { + { ao_sdcard_test_read, "x\0Test read" }, + { ao_sdcard_test_write, "y\0Test read" }, + { 0, NULL }, +}; +#endif + void ao_sdcard_init(void) { ao_spi_init_cs(AO_SDCARD_SPI_CS_PORT, (1 << AO_SDCARD_SPI_CS_PIN)); +#if SDCARD_DEBUG + ao_cmd_register(&ao_sdcard_cmds[0]); +#endif } - -