From 1aec91e5b3e5bb980f2029579bda36f306c9a000 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Thu, 13 Feb 2025 18:32:38 +0100 Subject: sdcard driver moved to drv/ --- fw/fe310/eos/dev/sdcard.c | 545 ---------------------------------------------- 1 file changed, 545 deletions(-) delete mode 100644 fw/fe310/eos/dev/sdcard.c (limited to 'fw/fe310/eos/dev/sdcard.c') diff --git a/fw/fe310/eos/dev/sdcard.c b/fw/fe310/eos/dev/sdcard.c deleted file mode 100644 index a2ee598..0000000 --- a/fw/fe310/eos/dev/sdcard.c +++ /dev/null @@ -1,545 +0,0 @@ -#include -#include -#include - -#include "eos.h" -#include "soc/timer.h" -#include "soc/spi.h" - -#include "spi.h" - -#include "sdc_crypto.h" -#include "sdcard.h" - -#define SDC_TIMEOUT_CMD 500 -#define SDC_TIMEOUT_READ 200 -#define SDC_TIMEOUT_WRITE 500 - -#define SDC_POLY_CRC7 0x09 -#define SDC_POLY_CRC16 0x1021 - -#define SDC_CMD_FLAG_CRC 0x01 -#define SDC_CMD_FLAG_NOCS 0x02 -#define SDC_CMD_FLAG_NOWAIT 0x04 -#define SDC_CMD_FLAG_RSTUFF 0x08 - -#define SDC_TOKEN_START_BLK 0xfe -#define SDC_TOKEN_START_BLKM 0xfc -#define SDC_TOKEN_STOP_TRAN 0xfd - -#define SDC_DRESP_MASK 0x1f -#define SDC_DRESP_ACCEPT 0x05 -#define SDC_DRESP_ERR_CRC 0x0b -#define SDC_DRESP_ERR_WRITE 0x0d - -#define SDC_R1_READY 0x00 - -#define SDC_R1_IDLE_STATE 0x01 -#define SDC_R1_ERASE_RESET 0x02 -#define SDC_R1_ILLEGAL_CMD 0x04 -#define SDC_R1_ERR_CMD_CRC 0x08 -#define SDC_R1_ERR_ERASE_SEQ 0x10 -#define SDC_R1_ERR_ADDR 0x20 -#define SDC_R1_ERR_PARAM 0x40 - -#define SDC_NCR 10 - -#define SDC_ERR(rv) ((rv < 0) ? rv : EOS_ERR) - -/* CMD */ -#define GO_IDLE_STATE 0 -#define SEND_OP_COND 1 -#define SEND_IF_COND 8 -#define SEND_CSD 9 -#define STOP_TRANSMISSION 12 -#define SET_BLOCKLEN 16 -#define READ_SINGLE_BLOCK 17 -#define READ_MULTIPLE_BLOCK 18 -#define WRITE_BLOCK 24 -#define WRITE_MULTIPLE_BLOCK 25 -#define ERASE_WR_BLK_START 32 -#define ERASE_WR_BLK_END 33 -#define ERASE 38 -#define APP_CMD 55 -#define READ_OCR 58 - -/* ACMD */ -#define SD_STATUS 13 -#define SET_WR_BLK_ERASE_COUNT 23 -#define SD_APP_OP_COND 41 - -static uint8_t sdc_type = 0; - -static uint8_t sdc_crc7(uint8_t crc, uint8_t b) { - int i; - - for (i=8; i--; b<<=1) { - crc <<= 1; - if ((b ^ crc) & 0x80) crc ^= SDC_POLY_CRC7; - } - return crc & 0x7f; -} - -static uint16_t sdc_crc16(uint16_t crc, uint8_t b) { - int i; - - crc = crc ^ ((uint16_t)b << 8); - for (i=8; i--;) { - if (crc & 0x8000) { - crc = (crc << 1) ^ SDC_POLY_CRC16; - } else { - crc <<= 1; - } - } - return crc; -} - -static uint32_t sdc_nto(uint32_t start, uint32_t timeout) { - uint32_t d = eos_time_delta_ms(start); - return (d > timeout) ? 0 : timeout - d; -} - -static uint8_t sdc_xchg8(uint8_t data) { - return eos_spi_xchg8(data, 0); -} - -static uint16_t sdc_xchg16(uint16_t data) { - return eos_spi_xchg16(data, 0); -} - -static uint32_t sdc_xchg32(uint32_t data) { - return eos_spi_xchg32(data, 0); -} - -static void sdc_buf_send(unsigned char *buffer, uint16_t len) { - int i; - - for (i=0; i> 24); - crc = sdc_crc7(crc, arg >> 16); - crc = sdc_crc7(crc, arg >> 8); - crc = sdc_crc7(crc, arg); - } - crc = (crc << 1) | 0x01; - sdc_xchg8(cmd); - sdc_xchg32(arg); - sdc_xchg8(crc); - if (flags & SDC_CMD_FLAG_RSTUFF) sdc_xchg8(0xff); - - i = SDC_NCR; - do { - ret = sdc_xchg8(0xff); - } while ((ret & 0x80) && --i); - if (ret & 0x80) return EOS_ERR_BUSY; - - return ret; -} - -static int sdc_ready(uint32_t timeout) { - uint8_t d = 0; - uint32_t start; - - if (timeout == 0) return EOS_ERR_BUSY; - - start = eos_time_get_tick(); - do { - if (eos_time_delta_ms(start) > timeout) break; - d = sdc_xchg8(0xff); - } while (d != 0xff); - if (d != 0xff) return EOS_ERR_BUSY; - - return EOS_OK; -} - -static int sdc_block_read(uint8_t *buffer, uint16_t len, uint32_t timeout) { - uint8_t token = 0xff; - uint32_t start; - - if (timeout == 0) return EOS_ERR_BUSY; - - start = eos_time_get_tick(); - do { - if (eos_time_delta_ms(start) > timeout) break; - token = sdc_xchg8(0xff); - } while (token == 0xff); - if (token == 0xff) return EOS_ERR_BUSY; - if (token != SDC_TOKEN_START_BLK) return EOS_ERR; - - sdc_buf_recv(buffer, len); - sdc_xchg16(0xffff); /* dummy CRC */ - - return EOS_OK; -} - -static int sdc_block_write(uint8_t token, uint8_t *buffer, uint16_t len, uint32_t timeout) { - uint8_t d; - int rv; - - rv = sdc_ready(timeout); - if (rv) return rv; - - sdc_xchg8(token); - if (buffer && len) { - sdc_buf_send(buffer, len); - sdc_xchg16(0xffff); /* dummy CRC */ - - d = sdc_xchg8(0xff); /* Response */ - if ((d & SDC_DRESP_MASK) != SDC_DRESP_ACCEPT) return EOS_ERR; - } - - return EOS_OK; -} - -static int sdc_cmd(uint8_t cmd, uint32_t arg, uint8_t flags, uint32_t timeout) { - int do_cs = !(flags & SDC_CMD_FLAG_NOCS); - int do_wait = !(flags & SDC_CMD_FLAG_NOWAIT); - int rv = EOS_OK; - - if (do_cs) sdc_select(); - if (do_wait) rv = sdc_ready(timeout); - if (rv) { - if (do_cs) sdc_deselect(); - return rv; - } - rv = sdc_xchg_cmd(cmd, arg, flags); - if (do_cs) sdc_deselect(); - return rv; -} - -static int sdc_acmd(uint8_t cmd, uint32_t arg, uint8_t flags, uint32_t timeout) { - int rv; - uint32_t start; - - start = eos_time_get_tick(); - rv = sdc_cmd(APP_CMD, 0, flags, timeout); - if (rv & ~SDC_R1_IDLE_STATE) return rv; - - if (flags & SDC_CMD_FLAG_NOCS) { - sdc_deselect(); - sdc_select(); - } - return sdc_cmd(cmd, arg, flags, sdc_nto(start, timeout)); -} - -static int sdc_init(uint32_t timeout) { - int rv, i; - uint8_t _type; - uint8_t ocr[4]; - uint32_t start; - - start = eos_time_get_tick(); - eos_time_sleep(100); - for (i=10; i--;) sdc_xchg8(0xff); /* 80 dummy cycles */ - - rv = sdc_cmd(GO_IDLE_STATE, 0, SDC_CMD_FLAG_CRC, SDC_TIMEOUT_CMD); - if (rv != SDC_R1_IDLE_STATE) return SDC_ERR(rv); - - sdc_select(); - rv = sdc_cmd(SEND_IF_COND, 0x1aa, SDC_CMD_FLAG_CRC | SDC_CMD_FLAG_NOCS, sdc_nto(start, timeout)); - switch (rv) { - case SDC_R1_IDLE_STATE: - for (i=0; i<4; i++) { /* R7 response */ - ocr[i] = sdc_xchg8(0xff); - } - sdc_deselect(); - if (ocr[2] == 0x01 && ocr[3] == 0xaa) { /* Check voltage range: 2.7-3.6V */ - do { - rv = sdc_acmd(SD_APP_OP_COND, 0x40000000, 0, sdc_nto(start, timeout)); - } while (rv == SDC_R1_IDLE_STATE); - if (rv != SDC_R1_READY) return SDC_ERR(rv); - - sdc_select(); - rv = sdc_cmd(READ_OCR, 0, SDC_CMD_FLAG_NOCS, sdc_nto(start, timeout)); - if (rv == SDC_R1_READY) { - for (i=0; i<4; i++) { /* R7 response */ - ocr[i] = sdc_xchg8(0xff); - } - sdc_deselect(); - } else { - sdc_deselect(); - return SDC_ERR(rv); - } - - _type = EOS_SDC_TYPE_SDC2; - if (ocr[0] & 0xc0) _type |= EOS_SDC_CAP_BLK; - } - break; - - case SDC_R1_IDLE_STATE | SDC_R1_ILLEGAL_CMD: - sdc_deselect(); - rv = sdc_acmd(SD_APP_OP_COND, 0, 0, sdc_nto(start, timeout)); - switch (rv) { - case SDC_R1_IDLE_STATE: - do { - rv = sdc_acmd(SD_APP_OP_COND, 0, 0, sdc_nto(start, timeout)); - } while (rv == SDC_R1_IDLE_STATE); - if (rv != SDC_R1_READY) return SDC_ERR(rv); - case SDC_R1_READY: - _type = EOS_SDC_TYPE_SDC1; - break; - - default: - do { - rv = sdc_cmd(SEND_OP_COND, 0, 0, sdc_nto(start, timeout)); - } while (rv == SDC_R1_IDLE_STATE); - if (rv != SDC_R1_READY) return SDC_ERR(rv); - _type = EOS_SDC_TYPE_MMC; - break; - - } - break; - - default: - sdc_deselect(); - return SDC_ERR(rv); - } - - if (!(_type & EOS_SDC_CAP_BLK)) { - rv = sdc_cmd(SET_BLOCKLEN, 512, 0, sdc_nto(start, timeout)); - if (rv != SDC_R1_READY) return SDC_ERR(rv); - } - - if (_type & EOS_SDC_TYPE_SDC) { - uint8_t csd[16]; - - sdc_select(); - rv = sdc_cmd(SEND_CSD, 0, SDC_CMD_FLAG_NOCS, sdc_nto(start, timeout)); - if (rv == SDC_R1_READY) { - rv = sdc_block_read(csd, 16, sdc_nto(start, timeout)); - } else { - rv = SDC_ERR(rv); - } - sdc_deselect(); - if (rv) return rv; - - for (i=0; i<16; i++) { - printf("%.2x ", csd[i]); - } - printf("\n"); - if (csd[10] & 0x40) _type |= EOS_SDC_CAP_ERASE_EN; - } - - eos_spi_set_div(EOS_SPI_DEV_SDC, 5); - sdc_type = _type; - return EOS_OK; -} - -int eos_sdc_init(uint8_t wakeup_cause) { - int rv; - - rv = eos_spi_select(EOS_SPI_DEV_SDC); - if (rv) return rv; - - rv = sdc_init(5000); - if (rv) { - printf("SDC ERROR\n"); - } else { - printf("SDC OK:%x\n", sdc_type); - } - eos_spi_deselect(); - - return EOS_OK; -} - -uint8_t eos_sdc_type(void) { - return sdc_type & EOS_SDC_TYPE_MASK; -} - -uint8_t eos_sdc_cap(void) { - return sdc_type & EOS_SDC_CAP_MASK; -} - -int eos_sdc_get_sect_count(uint32_t timeout, uint32_t *sectors) { - int rv; - uint8_t csd[16]; - uint32_t start; - - start = eos_time_get_tick(); - sdc_select(); - rv = sdc_cmd(SEND_CSD, 0, SDC_CMD_FLAG_NOCS, timeout); - if (rv == SDC_R1_READY) { - rv = sdc_block_read(csd, 16, sdc_nto(start, timeout)); - } else { - rv = SDC_ERR(rv); - } - sdc_deselect(); - if (rv) return rv; - - if ((csd[0] >> 6) == 1) { /* SDCv2 */ - *sectors = (csd[9] + (csd[8] << 8) + ((csd[7] & 0x3f) << 16) + 1) << 10; - } else { /* SDCv1 or MMC*/ - uint8_t n = (csd[5] & 0x0f) + (csd[10] >> 7) + ((csd[9] & 0x03) << 1) + 2; - *sectors = (csd[8] >> 6) + (csd[7] << 2) + ((csd[6] & 0x03) << 10) + 1; - *sectors = *sectors << (n - 9); - } - - return EOS_OK; -} - -int eos_sdc_get_blk_size(uint32_t timeout, uint32_t *size) { - int rv; - uint8_t rbl[64]; /* SD Status or CSD register */ - uint32_t start; - - start = eos_time_get_tick(); - sdc_select(); - if (sdc_type & EOS_SDC_TYPE_SDC2) { - rv = sdc_acmd(SD_STATUS, 0, SDC_CMD_FLAG_NOCS, timeout); - sdc_xchg8(0xff); /* R2 response */ - } else { - rv = sdc_cmd(SEND_CSD, 0, SDC_CMD_FLAG_NOCS, timeout); - } - if (rv == SDC_R1_READY) { - rv = sdc_block_read(rbl, (sdc_type & EOS_SDC_TYPE_SDC2) ? 64 : 16, sdc_nto(start, timeout)); - } else { - rv = SDC_ERR(rv); - } - sdc_deselect(); - if (rv) return rv; - - if (sdc_type & EOS_SDC_TYPE_SDC2) { - *size = 16UL << (rbl[10] >> 4); - } else if (sdc_type & EOS_SDC_TYPE_SDC1) { - *size = (((rbl[10] & 0x3f) << 1) + (rbl[11] >> 7) + 1) << ((rbl[13] >> 6) - 1); - } else { - *size = (((rbl[10] & 0x7c) >> 2) + 1) * (((rbl[11] & 0x03) << 3) + (rbl[11] >> 5) + 1); - } - - return EOS_OK; -} - -int eos_sdc_sync(uint32_t timeout) { - int rv; - - sdc_select(); - rv = sdc_ready(timeout); - sdc_deselect(); - - return rv; -} - -int eos_sdc_erase(uint32_t blk_start, uint32_t blk_end, uint32_t timeout) { - int rv; - uint32_t start; - - if (!(sdc_type & EOS_SDC_TYPE_SDC)) return EOS_ERR; - if (!(sdc_type & EOS_SDC_CAP_ERASE_EN)) return EOS_ERR; - if (!(sdc_type & EOS_SDC_CAP_BLK)) { - blk_start *= 512; - blk_end *= 512; - } - - start = eos_time_get_tick(); - rv = sdc_cmd(ERASE_WR_BLK_START, blk_start, 0, timeout); - if (rv != SDC_R1_READY) return SDC_ERR(rv); - - rv = sdc_cmd(ERASE_WR_BLK_END, blk_end, 0, sdc_nto(start, timeout)); - if (rv != SDC_R1_READY) return SDC_ERR(rv); - - rv = sdc_cmd(ERASE, 0, 0, sdc_nto(start, timeout)); - if (rv != SDC_R1_READY) return SDC_ERR(rv); - - return eos_sdc_sync(sdc_nto(start, timeout)); -} - -int eos_sdc_sect_read(uint32_t sect, unsigned int count, uint8_t *buffer) { - int rv; - uint8_t cmd = ((count == 1) ? READ_SINGLE_BLOCK : READ_MULTIPLE_BLOCK); - - if (!(sdc_type & EOS_SDC_CAP_BLK)) sect *= 512; - - sdc_select(); - rv = sdc_cmd(cmd, sect, SDC_CMD_FLAG_NOCS, SDC_TIMEOUT_CMD); - if (rv == SDC_R1_READY) { - int _rv = SDC_R1_READY; - - while (count) { - rv = sdc_block_read(buffer, 512, SDC_TIMEOUT_READ); - if (rv) break; - eos_sdcc_decrypt(sect, buffer); - buffer += 512; - count--; - } - if (cmd == READ_MULTIPLE_BLOCK) _rv = sdc_cmd(STOP_TRANSMISSION, 0, SDC_CMD_FLAG_NOCS | SDC_CMD_FLAG_NOWAIT | SDC_CMD_FLAG_RSTUFF, 0); - if (!rv && (_rv != SDC_R1_READY)) rv = SDC_ERR(_rv); - } else { - rv = SDC_ERR(rv); - } - sdc_deselect(); - - return rv; -} - -int eos_sdc_sect_write(uint32_t sect, unsigned int count, uint8_t *buffer) { - int rv; - - if (!(sdc_type & EOS_SDC_CAP_BLK)) sect *= 512; - - if (count == 1) { - sdc_select(); - rv = sdc_cmd(WRITE_BLOCK, sect, SDC_CMD_FLAG_NOCS, SDC_TIMEOUT_CMD); - if (rv == SDC_R1_READY) { - eos_sdcc_encrypt(sect, buffer); - rv = sdc_block_write(SDC_TOKEN_START_BLK, buffer, 512, SDC_TIMEOUT_WRITE); - } else { - rv = SDC_ERR(rv); - } - sdc_deselect(); - } else { - if (sdc_type & EOS_SDC_TYPE_SDC) { - rv = sdc_acmd(SET_WR_BLK_ERASE_COUNT, count, 0, SDC_TIMEOUT_CMD); - if (rv != SDC_R1_READY) return SDC_ERR(rv); - } - - sdc_select(); - rv = sdc_cmd(WRITE_MULTIPLE_BLOCK, sect, SDC_CMD_FLAG_NOCS, SDC_TIMEOUT_CMD); - if (rv == SDC_R1_READY) { - int _rv; - - while (count) { - eos_sdcc_encrypt(sect, buffer); - rv = sdc_block_write(SDC_TOKEN_START_BLKM, buffer, 512, SDC_TIMEOUT_WRITE); - if (rv) break; - buffer += 512; - count--; - } - _rv = sdc_block_write(SDC_TOKEN_STOP_TRAN, NULL, 0, SDC_TIMEOUT_WRITE); - if (!rv && (_rv != SDC_R1_READY)) rv = SDC_ERR(_rv); - } else { - rv = SDC_ERR(rv); - } - sdc_deselect(); - } - - return rv; -} -- cgit v1.2.3