- for (int i = 0; i < TIMEOUT_NAC; i++)
- {
- token = kfile_getc(fd);
- if (token != 0xff)
- {
- if (token == SD_STARTTOKEN)
- {
- if (kfile_read(fd, buf, len) == len)
- {
- if (kfile_read(fd, &crc, sizeof(crc)) == sizeof(crc))
- /* check CRC here if needed */
- return true;
- else
- LOG_ERR("get_block error getting crc\n");
- }
- else
- LOG_ERR("get_block len error: %d\n", (int)len);
- }
- else
- LOG_ERR("get_block token error: %02X\n", token);
-
- return false;
- }
- }
-
- LOG_ERR("get_block timeout waiting token\n");
- return false;
-}
-
-#define SD_SELECT() \
-do \
-{ \
- if (!sd_select(true)) \
- { \
- LOG_ERR("%s failed, card busy\n", __func__); \
- return EOF; \
- } \
-} \
-while (0)
-
-#define SD_SETBLOCKLEN 0x50
-
-static int16_t sd_setBlockLen(uint32_t newlen)
-{
- SD_SELECT();
-
- int16_t r1 = sd_sendCommand(SD_SETBLOCKLEN, newlen, 0);
-
- sd_select(false);
- return r1;
-}
-
-#define SD_SEND_CSD 0x49
-
-static int16_t sd_getCSD(CardCSD *csd)
-{
- SD_SELECT();
-
- int16_t r1 = sd_sendCommand(SD_SEND_CSD, 0, 0);
-
- if (r1)
- {
- LOG_ERR("send_csd failed: %04X\n", r1);
- sd_select(false);
- return r1;
- }
-
- uint8_t buf[16];
- bool res = sd_getBlock(buf, sizeof(buf));
- sd_select(false);
-
- if (res)
- {
- uint16_t mult = (1L << ((((buf[9] & 0x03) << 1) | ((buf[10] & 0x80) >> 7)) + 2));
- uint16_t c_size = (((uint16_t)(buf[6] & 0x03)) << 10) | (((uint16_t)buf[7]) << 2) |
- (((uint16_t)(buf[8] & 0xC0)) >> 6);
-
- csd->block_len = (1L << (buf[5] & 0x0F));
- csd->block_num = (c_size + 1) * mult;
- csd->capacity = (csd->block_len * csd->block_num) >> 20; // in MB
-
- LOG_INFO("block_len %d bytes, block_num %ld, total capacity %dMB\n", csd->block_len, csd->block_num, csd->capacity);
- return 0;
- }
- else
- return EOF;
-}
-
-
-#define SD_READ_SINGLEBLOCK 0x51
-
-static int16_t sd_readBlock(void *buf, uint32_t addr)
-{
- SD_SELECT();
-
- int16_t r1 = sd_sendCommand(SD_READ_SINGLEBLOCK, addr, 0);
-
- if (r1)
- {
- LOG_ERR("read single block failed: %04X\n", r1);
- sd_select(false);
- return r1;
- }
-
- bool res = sd_getBlock(buf, SD_DEFAULT_BLOCKLEN);
- sd_select(false);
- if (!res)
- {
- LOG_ERR("read single block failed reading data\n");
- return EOF;
- }
- else
- return 0;
-}