worked on FileSystem, started to migrate logging class
This commit is contained in:
@@ -9,11 +9,13 @@
|
||||
#define TEENSY_SD_PIN_MISO 43
|
||||
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
// http://www.dejazzer.com/ee379/lecture_notes/lec12_sd_card.pdf
|
||||
// https://www.convict.lu/pdf/ProdManualSDCardv1.9.pdf
|
||||
// http://rjhcoding.com/avrc-sd-interface-3.php
|
||||
template <typename SPI, int PIN_CS> class SDCard {
|
||||
|
||||
|
||||
SPI& spi;
|
||||
|
||||
union R1 { // SanDisk Manual Page 5-13
|
||||
@@ -64,7 +66,7 @@ public:
|
||||
bool init() {
|
||||
|
||||
MyGPIO::setOutput(PIN_CS);
|
||||
debugMod(NAME, "init()");
|
||||
Log::addInfo(NAME, "init()");
|
||||
|
||||
// RESET: MOSI = 1, CS = 1 (deselected!!), at least 74 Clocks
|
||||
deselect();
|
||||
@@ -74,7 +76,7 @@ public:
|
||||
for (uint8_t i = 0; ; ++i) {
|
||||
const R1 res = cmd0();
|
||||
if (res.raw == 1) {break;}
|
||||
if (i == 4) {debugMod(NAME, "init failed"); return false;}
|
||||
if (i == 4) {Log::addError(NAME, "init failed"); return false;}
|
||||
delay(50);
|
||||
}
|
||||
|
||||
@@ -82,13 +84,13 @@ public:
|
||||
// TODO?
|
||||
// Version 2.0 Card
|
||||
Rcmd8 r8 = cmd8();
|
||||
|
||||
|
||||
if (r8.state.raw == 1) {
|
||||
debugMod(NAME, "V2/V3 Card");
|
||||
Log::addInfo(NAME, "V2/V3 Card");
|
||||
if (r8.data[2] == 0x01 && r8.data[3] == 0xAA) {
|
||||
debugMod(NAME, "Pattern Correct");
|
||||
Log::addInfo(NAME, "Pattern Correct");
|
||||
} else {
|
||||
debugMod(NAME, "Pattern Mismatch");
|
||||
Log::addError(NAME, "Pattern Mismatch");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -103,70 +105,35 @@ public:
|
||||
for (uint8_t i = 0; ; ++i) {
|
||||
delay(100);
|
||||
R1 r1 = acmd41(hcs);
|
||||
if (i == 8) {debugMod(NAME, "init failed"); return false;}
|
||||
if (r1.raw == 0) {break;} // finished
|
||||
if (r1.raw == 1) {continue;} // card is still idle
|
||||
if (r1.raw > 1) {debugMod(NAME, "init failed"); return false;}
|
||||
if (i == 8) {Log::addError(NAME, "init failed"); return false;}
|
||||
if (r1.raw == 0) {break;} // finished
|
||||
if (r1.raw == 1) {continue;} // card is still idle
|
||||
if (r1.raw > 1) {Log::addError(NAME, "init failed"); return false;}
|
||||
}
|
||||
|
||||
debugMod(NAME, "init OK");
|
||||
Log::addInfo(NAME, "init OK");
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
uint32_t read(uint32_t addr, uint32_t size, uint8_t* dst) {
|
||||
|
||||
/** read a single block of 512 bytes, addr = byteAddr/512 */
|
||||
bool readSingleBlock(LBA512 addr, uint8_t* dst) {
|
||||
|
||||
uint32_t read = 0;
|
||||
uint32_t readAddr = addr & (0xFFFFFFFF - 512); // 512 byte aligned staring address
|
||||
|
||||
if (readAddr != addr) { // non-aligned first read?
|
||||
uint8_t buf[512];
|
||||
uint16_t cOff = (addr-readAddr); // skip the unneeded bytes
|
||||
uint16_t cSize = 512 - cOff;
|
||||
readSingleBlock(readAddr, buf); // read a full block
|
||||
memcpy(dst, buf+cOff, cSize); // copy only the required bytes
|
||||
size -= cSize;
|
||||
dst += cSize;
|
||||
read += cSize;
|
||||
readAddr += 512;
|
||||
}
|
||||
|
||||
while(size >= 512) {
|
||||
readSingleBlock(readAddr, dst);
|
||||
readAddr += 512;
|
||||
dst += 512;
|
||||
read += 512;
|
||||
size -= 512;
|
||||
}
|
||||
|
||||
if (size > 0) {
|
||||
uint8_t buf[512];
|
||||
readSingleBlock(readAddr, buf);
|
||||
memcpy(dst, buf, size);
|
||||
read += size;
|
||||
}
|
||||
|
||||
return read;
|
||||
|
||||
}
|
||||
|
||||
/** read a single block of 512 bytes */
|
||||
bool readSingleBlock(uint32_t addr, uint8_t* dst) {
|
||||
|
||||
addr = addr / 512;
|
||||
sendCMD(17, addr>>24, addr>>16, addr>>8, addr>>0, 0xFF);
|
||||
R1 res; readResponse(&res.raw, 1);
|
||||
debugMod2(NAME, "readSingleBlock(%08x): %02x", addr, res.raw);
|
||||
|
||||
|
||||
Log::addInfo(NAME, "readBlock(%d*512): %02x", addr, res.raw);
|
||||
|
||||
// read command OK?
|
||||
if (res.raw != 0) {endCMD(); return false;}
|
||||
if (res.raw != 0) {Log::addError(NAME, "failed"); endCMD(); return false;}
|
||||
|
||||
// wait for data to become available
|
||||
for (uint16_t i = 0; ; ++i) {
|
||||
uint8_t res = spi.readWriteByte(0xFF);
|
||||
if (res == 0xFE) {break;} // available!
|
||||
if (res != 0xFF) {debugMod(NAME, "invalid"); endCMD(); return false;} // invalid response
|
||||
if (i > 1024) {debugMod(NAME, "timeout"); endCMD(); return false;} // timeout
|
||||
if (res != 0xFF) {Log::addError(NAME, "invalid"); endCMD(); return false;} // invalid response
|
||||
if (i > 1024) {Log::addError(NAME, "timeout"); endCMD(); return false;} // timeout
|
||||
}
|
||||
|
||||
// read data
|
||||
@@ -181,6 +148,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
/** send a new command */
|
||||
@@ -207,7 +175,7 @@ private:
|
||||
sendCMD(0, 0x00, 0x00, 0x00, 0x00, 0x4A);
|
||||
R1 res; readResponse(&res.raw, 1);
|
||||
endCMD();
|
||||
debugMod1(NAME, "cmd0: %02x", res.raw);
|
||||
Log::addInfo(NAME, "cmd0: %02x", res.raw);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -221,7 +189,7 @@ private:
|
||||
//}
|
||||
Rcmd8 res; readResponse(res.raw, 5);
|
||||
endCMD();
|
||||
debugMod5(NAME, "cmd8: %02x %02x %02x %02x %02x", res.raw[0], res.raw[1], res.raw[2], res.raw[3], res.raw[4]);
|
||||
Log::addInfo(NAME, "cmd8: %02x %02x %02x %02x %02x", res.raw[0], res.raw[1], res.raw[2], res.raw[3], res.raw[4]);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -233,7 +201,7 @@ private:
|
||||
sendCMD(58, 0x00, 0x00, 0x00, 0x00, 0xFF);//0b0111010);
|
||||
R3 res; readResponse(res.raw, 5); // typical response: 0x01 0x00 0xff 0x80 0x00
|
||||
endCMD();
|
||||
debugMod5(NAME, "cmd58: %02x %02x %02x %02x %02x", res.raw[0], res.raw[1], res.raw[2], res.raw[3], res.raw[4]);
|
||||
Log::addInfo(NAME, "cmd58: %02x %02x %02x %02x %02x", res.raw[0], res.raw[1], res.raw[2], res.raw[3], res.raw[4]);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -244,7 +212,7 @@ private:
|
||||
sendCMD(55, 0x00, 0x00, 0x00, 0x00, 0xFF);
|
||||
R1 res; readResponse(&res.raw, 1);
|
||||
endCMD();
|
||||
debugMod1(NAME, "cmd55: %02x", res.raw);
|
||||
Log::addInfo(NAME, "cmd55: %02x", res.raw);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -253,7 +221,7 @@ private:
|
||||
sendCMD(41, val>>24, val>>16, val>>8, val>>0, 0xFF);
|
||||
R1 res; readResponse(&res.raw, 1);
|
||||
endCMD();
|
||||
debugMod1(NAME, "acmd41: %02x", res.raw);
|
||||
Log::addInfo(NAME, "acmd41: %02x", res.raw);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -271,7 +239,7 @@ private:
|
||||
// NOTE: it is IMPORTANT to send 0xFF to the card while reading its responses!
|
||||
|
||||
// wait for the first byte to arrive and read it
|
||||
for (uint8_t i = 0; i < 4; ++i) {
|
||||
for (uint8_t i = 0; i < 8; ++i) {
|
||||
dst[0] = spi.readWriteByte(0xFF);
|
||||
if ( (dst[0] & 0x80) == 0 ) {break;}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user