00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00030 #ifndef SFBSDRAW_H
00031 #define SFBSDRAW_H
00032
00033 #include "SFBTypes.h"
00034 #include "SFBConstants.h"
00035
00036 #define SDRAW_BLOCK_SIZE_BIT_COUNT 9
00037 #define SDRAW_BLOCK_SIZE (1<<(SDRAW_BLOCK_SIZE_BIT_COUNT)) // 512 bytes per block
00038 #define SDRAW_BLOCK_SIZE_BIT_MASK ((SDRAW_BLOCK_SIZE)-1)
00039
00044 struct SDRawDiskInfo {
00045 u32 serialNumber;
00046 u32 blockCount;
00047 u8 manufacturer;
00048 u8 oem[2+1];
00049 u8 product[5+1];
00050 u8 revision;
00051 u8 year;
00052 u8 month;
00053 u8 format;
00054 bool copy;
00055 bool writeProtect;
00056 bool writeProtectTemporary;
00057 };
00058
00113 class SDRaw {
00114 public:
00118 enum State {
00119 NOT_BEGUN=0,
00120 UNINITTED,
00121 RESET_FAILED,
00122 CRC_ON_FAILED,
00123 TYPE_CHECK_FAILED,
00124 OP_COND_FAILED,
00125 READ_OCR_FAILED,
00126 CONFIG_FAILED,
00127 ACTIVE,
00128 INACTIVE_READ,
00129 INACTIVE_WRITE,
00130 ERROR_READ_SINGLE_BLOCK,
00131 ERROR_READ_REGISTER,
00132 ERROR_READ_TIMEOUT_DATA,
00133 ERROR_READ_CRC_DATA,
00134 ERROR_BAD_CSD_VERSION,
00135 ERROR_WRITE_TIMEOUT_DATA,
00136 ERROR_WRITE_SINGLE_BLOCK
00137 };
00138
00147 void begin(u8 face) ;
00148
00165 void begin(u8 face, u8 CSPin, u8 clkPin, u8 MOSIpin, u8 MISOpin) ;
00166
00173 bool end() ;
00174
00178 u32 getState() { return status; }
00179
00185 u32 getBlockCount() { return isActive() ? blockCapacity : 0; }
00186
00191 u64 getByteCount() { return ((u64) getBlockCount())<<SDRAW_BLOCK_SIZE_BIT_COUNT; }
00192
00197 u8 getFace() { return sdFace; }
00198
00210 bool init() ;
00211
00214 bool isActive() { return getState()==ACTIVE; }
00215
00223 bool getInfo(SDRawDiskInfo & info) ;
00224
00248 bool setBlockBuffer(u8 * buffer, u32 bufferLength) ;
00249
00281 bool read(u64 address, u8* data, u32 length) ;
00282
00312 bool readBlock(u32 blockNumber, u8* buffer, u32 blockOffset = 0, u32 length = 512) ;
00313
00342 bool write(u64 address, const u8* data, u32 length) ;
00343
00359 bool writeBlock(u32 blockNumber, const u8* buffer) ;
00360
00369 bool sync() ;
00370
00376 bool isSDHC() { return (flags&HC_CARD); }
00377
00381 void setSpiLog(bool val) { if (val) flags |= SPI_LOG; else flags &= ~SPI_LOG; }
00382
00394 u32 readStatus() ;
00395
00396 private:
00397 enum { SHORT_TRIES = 50, LONG_TRIES = 50000 };
00398
00399 enum {
00400 BLOCK_DIRTY = 0x01,
00401 HC_CARD = 0x02,
00402 SPI_LOG = 0x04,
00403 FLAG_RSRV3 = 0x08,
00404 FLAG_RSRV4 = 0x10,
00405 FLAG_RSRV5 = 0x20,
00406 FLAG_RSRV6 = 0x40,
00407 FLAG_RSRV7 = 0x80
00408 };
00409 u32 blockCapacity;
00410 u32 cachedBlockNumber;
00411 u8 * cachedBlock;
00412 u8 flags;
00413 u8 status;
00414 u8 sdFace;
00415 u8 sdCSel;
00416 u8 sdClk;
00417 u8 sdMOSI;
00418 u8 sdMISO;
00419
00420 void startTransaction() ;
00421 void endTransaction() ;
00422
00423 bool dieWith(u32 newStatus) ;
00424
00425 bool readRegister(u32 cmd, u8 reg[16]);
00426
00427 void sendBitsSlow(u32 data, u32 bitCount) ;
00428 u32 recvBitsSlow(u32 bitCount) ;
00429
00430 void sendBits(u32 bits, u32 bitCount) ;
00431 u32 recvBits(u32 bitCount) ;
00432
00433 void sendByte(u8 data) { sendBits(data,8); }
00434 u8 recvByte() { return (u8) recvBits(8); }
00435
00436 u8 sendCmd(u8 cmd, u32 arg) ;
00437
00438 bool loadCache(u32 blockNumber) ;
00439 bool writeBuffered(u64 offset, const u8* buffer, u32 length) ;
00440 bool readBuffered(u64 offset, u8* buffer, u32 length) ;
00441
00442 };
00443
00444 #endif