/* Arduino WaveHC Library * Copyright (C) 2008 by William Greiman * * This file is part of the Arduino FAT16 Library * * This Library is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This Library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with the Arduino Fat16 Library. If not, see * . */ #ifndef SdReader_h #define SdReader_h #include /** * \file * SdReader class */ /** * Some SD card are very sensitive to the SPI bus speed for initialization. * Try setting SPI_INIT_SLOW nonzero if you have initialization problems. * * Set SPI_INIT_SLOW nonzero to reduce the SPI bus speed for SD initaizaton * to F_CPU/128. F_CPU/64 is used if */ #define SPI_INIT_SLOW 0 /** * Default card SPI speed. Change to true for Wave Shield V1.0 * The SPI speed is 4 Mhz for 'true' and 8 Mhz for 'false'. */ #define SPI_DEFAULT_HALF_SPEED false /** read timeout ms */ #define SD_READ_TIMEOUT 300 // SD card errors /** timeout error for command CMD0 */ #define SD_CARD_ERROR_CMD0 0X1 /** CMD8 was not accepted - not a valid SD card*/ #define SD_CARD_ERROR_CMD8 0X2 /** card returned an error response for CMD17 (read block) */ #define SD_CARD_ERROR_CMD17 0X3 /** card returned an error response for CMD24 (write block) */ #define SD_CARD_ERROR_CMD24 0X4 /** card returned an error response for CMD58 (read OCR) */ #define SD_CARD_ERROR_CMD58 0X5 /** card's ACMD41 initialization process timeout */ #define SD_CARD_ERROR_ACMD41 0X6 /** card returned a bad CSR version field */ #define SD_CARD_ERROR_BAD_CSD 0X7 /** read CID or CSD failed */ #define SD_CARD_ERROR_READ_REG 0X8 /** bad response echo from CMD8 */ #define SD_CARD_ERROR_CMD8_ECHO 0X09 /** timeout while waiting for start of read data */ #define SD_CARD_ERROR_READ_TIMEOUT 0XD /** card returned an error token instead of read data */ #define SD_CARD_ERROR_READ 0X10 // // card types /** Standard capacity V1 SD card */ #define SD_CARD_TYPE_SD1 1 /** Standard capacity V2 SD card */ #define SD_CARD_TYPE_SD2 2 /** High Capacity SD card */ #define SD_CARD_TYPE_SDHC 3 //------------------------------------------------------------------------------ /** * \class SdReader * \brief Hardware access class for SD flash cards * * Supports raw access to SD and SDHC flash memory cards. * */ class SdReader { uint32_t block_; uint8_t errorCode_; uint8_t errorData_; uint8_t inBlock_; uint16_t offset_; uint8_t partialBlockRead_; uint8_t response_; uint8_t type_; uint8_t cardCommand(uint8_t cmd, uint32_t arg); void error(uint8_t code) { errorCode_ = code; } void error(uint8_t code, uint8_t data) { errorCode_ = code; errorData_ = data; } uint8_t readRegister(uint8_t cmd, uint8_t *dst); void type(uint8_t value) { type_ = value; } uint8_t waitNotBusy(uint16_t timeoutMillis); uint8_t waitStartBlock(void); public: /** Construct an instance of SdReader. */ SdReader(void) : errorCode_(0), inBlock_(0), partialBlockRead_(0), type_(0){}; uint32_t cardSize(void); /** \return error code for last error */ uint8_t errorCode(void) { return errorCode_; } /** \return error data for last error */ uint8_t errorData(void) { return errorData_; } uint8_t init(uint8_t slow = SPI_DEFAULT_HALF_SPEED); /** * Enable or disable partial block reads. * * Enabling partial block reads improves performance by allowing a block * to be read over the SPI bus as several sub-blocks. Errors will occur * if the time between reads is too long since the SD card will timeout. * * Use this for applications like the Adafruit Wave Shield. * * \param[in] value The value TRUE (non-zero) or FALSE (zero).) */ void partialBlockRead(uint8_t value) { readEnd(); partialBlockRead_ = value; } /** * Read a 512 byte block from a SD card device. * * \param[in] block Logical block to be read. * \param[out] dst Pointer to the location that will receive the data. * * \return The value one, true, is returned for success and * the value zero, false, is returned for failure. */ uint8_t readBlock(uint32_t block, uint8_t *dst) { return readData(block, 0, dst, 512); } uint8_t readData(uint32_t block, uint16_t offset, uint8_t *dst, uint16_t count); /** * Read a cards CID register. The CID contains card identification information * such as Manufacturer ID, Product name, Product serial number and * Manufacturing date. */ /*! @brief Read a cards CID register. The CID contains card identification information such as Manufacturer ID, Product name, Product serial number and Manufacturing date. @param cid the pointer to the cid struct the data should be placed in @returns the return code after the read */ uint8_t readCID(cid_t &cid) { return readRegister(CMD10, (uint8_t *)&cid); } /*! @brief Read a cards CSD register. The CSD contains Card-Specific Data that provides information regarding access to the card contents. @param csd pointer to the struct the data should be placed in. @returns the return code after the read. */ uint8_t readCSD(csd_t &csd) { return readRegister(CMD9, (uint8_t *)&csd); } void readEnd(void); /*! @brief Return the card type: SD V1, SD V2 or SDHC @returns the type */ uint8_t type() { return type_; } }; #endif // SdReader_h