@@ -22,7 +22,7 @@ const uint8_t BUF_DIM = 100; | |||
uint8_t buf[BUF_DIM]; | |||
const uint32_t FILE_SIZE = 1000000; | |||
const uint16_t NWRITE = FILE_SIZE/BUF_DIM; | |||
const uint32_t NWRITE = FILE_SIZE/BUF_DIM; | |||
//------------------------------------------------------------------------------ | |||
// print error msg, any SD error codes, and halt. | |||
// store messages in flash | |||
@@ -107,7 +107,7 @@ void setup() { | |||
Serial.println(F("Writing test.bin to sd1")); | |||
// write data to /Dir1/test.bin on sd1 | |||
for (uint16_t i = 0; i < NWRITE; i++) { | |||
for (uint32_t i = 0; i < NWRITE; i++) { | |||
if (file1.write(buf, sizeof(buf)) != sizeof(buf)) { | |||
error("file1.write"); | |||
} |
@@ -166,12 +166,14 @@ void loop() { | |||
} | |||
// fill buf with known data | |||
for (uint16_t i = 0; i < (BUF_SIZE-2); i++) { | |||
buf[i] = 'A' + (i % 26); | |||
if (BUF_SIZE > 1) { | |||
for (size_t i = 0; i < (BUF_SIZE - 2); i++) { | |||
buf[i] = 'A' + (i % 26); | |||
} | |||
buf[BUF_SIZE-2] = '\r'; | |||
} | |||
buf[BUF_SIZE-2] = '\r'; | |||
buf[BUF_SIZE-1] = '\n'; | |||
cout << F("FILE_SIZE_MB = ") << FILE_SIZE_MB << endl; | |||
cout << F("BUF_SIZE = ") << BUF_SIZE << F(" bytes\n"); | |||
cout << F("Starting write test, please wait.") << endl << endl; | |||
@@ -241,6 +243,7 @@ void loop() { | |||
m = micros() - m; | |||
totalLatency += m; | |||
if (buf[BUF_SIZE-1] != '\n') { | |||
error("data check error"); | |||
} | |||
if (skipLatency) { |
@@ -61,7 +61,7 @@ void loop() { | |||
} | |||
// fill buf with known data | |||
for (uint16_t i = 0; i < (BUF_SIZE-2); i++) { | |||
for (size_t_t i = 0; i < (BUF_SIZE-2); i++) { | |||
buf[i] = 'A' + (i % 26); | |||
} | |||
buf[BUF_SIZE-2] = '\r'; |
@@ -16,7 +16,7 @@ const uint8_t BUF_DIM = 100; | |||
uint8_t buf[BUF_DIM]; | |||
const uint32_t FILE_SIZE = 1000000; | |||
const uint16_t NWRITE = FILE_SIZE/BUF_DIM; | |||
const uint32_t NWRITE = FILE_SIZE/BUF_DIM; | |||
//------------------------------------------------------------------------------ | |||
// print error msg, any SD error codes, and halt. | |||
// store messages in flash | |||
@@ -107,7 +107,7 @@ void setup() { | |||
Serial.println(F("Writing test.bin to sd1")); | |||
// write data to /Dir1/test.bin on sd1 | |||
for (uint16_t i = 0; i < NWRITE; i++) { | |||
for (uint32_t i = 0; i < NWRITE; i++) { | |||
if (file1.write(buf, sizeof(buf)) != sizeof(buf)) { | |||
sd1.errorExit("sd1.write"); | |||
} |
@@ -1,5 +1,5 @@ | |||
name=SdFat | |||
version=2.0.0-beta.3 | |||
version=2.0.0-beta.4 | |||
license=MIT | |||
author=Bill Greiman <fat16lib@sbcglobal.net> | |||
maintainer=Bill Greiman <fat16lib@sbcglobal.net> |
@@ -602,17 +602,17 @@ int ExFatFile::read(void* buf, size_t count) { | |||
#if USE_MULTI_SECTOR_IO | |||
} else if (toRead >= 2*m_vol->bytesPerSector()) { | |||
uint32_t ns = toRead >> m_vol->bytesPerSectorShift(); | |||
if (!isContiguous()) { | |||
uint32_t maxNs = m_vol->sectorsPerCluster() | |||
- (clusterOffset >> m_vol->bytesPerSectorShift()); | |||
if (ns > maxNs) { | |||
ns = maxNs; | |||
} | |||
// Limit writes to current cluster. | |||
uint32_t maxNs = m_vol->sectorsPerCluster() | |||
- (clusterOffset >> m_vol->bytesPerSectorShift()); | |||
if (ns > maxNs) { | |||
ns = maxNs; | |||
} | |||
n = ns << m_vol->bytesPerSectorShift(); | |||
if (m_vol->dataCacheSector() <= sector | |||
// Check for cache sector in read range. | |||
if (sector <= m_vol->dataCacheSector() | |||
&& m_vol->dataCacheSector() < (sector + ns)) { | |||
// flush cache if a sector is in the cache | |||
// Flush cache if a cache sector is in the range. | |||
if (!m_vol->dataCacheSync()) { | |||
DBG_FAIL_MACRO; | |||
goto fail; |
@@ -748,9 +748,10 @@ size_t ExFatFile::write(const void* buf, size_t nbyte) { | |||
ns = maxNs; | |||
} | |||
n = ns << m_vol->bytesPerSectorShift(); | |||
if (m_vol->dataCacheSector() <= sector | |||
// Check for cache sector in write range. | |||
if (sector <= m_vol->dataCacheSector() | |||
&& m_vol->dataCacheSector() < (sector + ns)) { | |||
// invalidate cache if sector is in cache | |||
// Invalidate cache if cache sector is in the range. | |||
m_vol->dataCacheInvalidate(); | |||
} | |||
if (!m_vol->writeSectors(sector, src, ns)) { |
@@ -721,17 +721,18 @@ int FatFile::read(void* buf, size_t nbyte) { | |||
memcpy(dst, src, n); | |||
#if USE_MULTI_SECTOR_IO | |||
} else if (toRead >= 2*m_vol->bytesPerSector()) { | |||
uint8_t ns = toRead >> m_vol->bytesPerSectorShift(); | |||
uint32_t ns = toRead >> m_vol->bytesPerSectorShift(); | |||
if (!isRootFixed()) { | |||
uint8_t mb = m_vol->sectorsPerCluster() - sectorOfCluster; | |||
uint32_t mb = m_vol->sectorsPerCluster() - sectorOfCluster; | |||
if (mb < ns) { | |||
ns = mb; | |||
} | |||
} | |||
n = ns << m_vol->bytesPerSectorShift(); | |||
if (m_vol->cacheSectorNumber() <= sector | |||
// Check for cache sector in read range. | |||
if (sector <= m_vol->cacheSectorNumber() | |||
&& sector < (m_vol->cacheSectorNumber() + ns)) { | |||
// flush cache if a sector is in the cache | |||
// Flush cache if a cache sector is in the range. | |||
if (!m_vol->cacheSyncData()) { | |||
DBG_FAIL_MACRO; | |||
goto fail; | |||
@@ -1360,15 +1361,16 @@ size_t FatFile::write(const void* buf, size_t nbyte) { | |||
#if USE_MULTI_SECTOR_IO | |||
} else if (nToWrite >= 2*m_vol->bytesPerSector()) { | |||
// use multiple sector write command | |||
uint8_t maxSectors = m_vol->sectorsPerCluster() - sectorOfCluster; | |||
uint8_t nSector = nToWrite >> m_vol->bytesPerSectorShift(); | |||
uint32_t maxSectors = m_vol->sectorsPerCluster() - sectorOfCluster; | |||
uint32_t nSector = nToWrite >> m_vol->bytesPerSectorShift(); | |||
if (nSector > maxSectors) { | |||
nSector = maxSectors; | |||
} | |||
n = nSector << m_vol->bytesPerSectorShift(); | |||
if (m_vol->cacheSectorNumber() <= sector | |||
// Check for cache sector in write range. | |||
if (sector <= m_vol->cacheSectorNumber() | |||
&& sector < (m_vol->cacheSectorNumber() + nSector)) { | |||
// invalidate cache if sector is in cache | |||
// Invalidate cache if cache sector is in the range. | |||
m_vol->cacheInvalidate(); | |||
} | |||
if (!m_vol->writeSectors(sector, src, nSector)) { |
@@ -24,28 +24,35 @@ | |||
*/ | |||
#define FREE_STACK_CPP | |||
#include "FreeStack.h" | |||
#if HAS_UNUSED_STACK | |||
#ifdef __AVR__ | |||
inline char* heapEnd() { | |||
#if defined(HAS_UNUSED_STACK) && HAS_UNUSED_STACK | |||
//------------------------------------------------------------------------------ | |||
inline char* stackBegin() { | |||
#if defined(__AVR__) | |||
return __brkval ? __brkval : &__bss_end; | |||
} | |||
inline char* stackPointer() { | |||
return reinterpret_cast<char*>(SP); | |||
} | |||
#elif defined(__IMXRT1062__) | |||
return reinterpret_cast<char*>(&_ebss); | |||
#elif defined(__arm__) | |||
inline char* heapEnd() { | |||
return reinterpret_cast<char*>(sbrk(0)); | |||
#else // defined(__AVR__) | |||
#error "undefined stackBegin" | |||
#endif // defined(__AVR__) | |||
} | |||
//------------------------------------------------------------------------------ | |||
inline char* stackPointer() { | |||
#if defined(__AVR__) | |||
return reinterpret_cast<char*>(SP); | |||
#elif defined(__arm__) | |||
register uint32_t sp asm("sp"); | |||
return reinterpret_cast<char*>(sp); | |||
#else // defined(__AVR__) | |||
#error "undefined stackPointer" | |||
#endif // defined(__AVR__) | |||
} | |||
#endif // #elif define(__arm__) | |||
//------------------------------------------------------------------------------ | |||
/** Stack fill pattern. */ | |||
const char FILL = 0x55; | |||
void FillStack() { | |||
char* p = heapEnd(); | |||
char* p = stackBegin(); | |||
char* top = stackPointer(); | |||
while (p < top) { | |||
*p++ = FILL; | |||
@@ -54,7 +61,7 @@ void FillStack() { | |||
//------------------------------------------------------------------------------ | |||
// May fail if malloc or new is used. | |||
int UnusedStack() { | |||
char* h = heapEnd(); | |||
char* h = stackBegin(); | |||
char* top = stackPointer(); | |||
int n; | |||
@@ -70,4 +77,4 @@ int UnusedStack() { | |||
} | |||
return n; | |||
} | |||
#endif // HAS_UNUSED_STACK | |||
#endif // defined(HAS_UNUSED_STACK) && HAS_UNUSED_STACK |
@@ -49,7 +49,14 @@ inline int FreeStack() { | |||
inline int FreeStack() { | |||
return System.freeMemory(); | |||
} | |||
#elif defined(__arm__) && !defined(__IMXRT1062__) | |||
#elif defined(__IMXRT1062__) | |||
#define HAS_UNUSED_STACK 1 | |||
extern uint8_t _ebss; | |||
inline int FreeStack() { | |||
register uint32_t sp asm("sp"); | |||
return reinterpret_cast<char*>(sp) - reinterpret_cast<char*>(&_ebss); | |||
} | |||
#elif defined(__arm__) | |||
#define HAS_UNUSED_STACK 1 | |||
extern "C" char* sbrk(int incr); | |||
inline int FreeStack() { | |||
@@ -64,7 +71,7 @@ inline int FreeStack() { | |||
return 0; | |||
} | |||
#endif // defined(__AVR__) || defined(DOXYGEN) | |||
#ifdef HAS_UNUSED_STACK | |||
#if defined(HAS_UNUSED_STACK) || defined(DOXYGEN) | |||
/** Fill stack with 0x55 pattern */ | |||
void FillStack(); | |||
/** | |||
@@ -81,5 +88,5 @@ int UnusedStack(); | |||
#define HAS_UNUSED_STACK 0 | |||
inline void FillStack() {} | |||
inline int UnusedStack() {return 0;} | |||
#endif // HAS_UNUSED_STACK | |||
#endif // defined(HAS_UNUSED_STACK) | |||
#endif // FreeStack_h |
@@ -133,6 +133,8 @@ const uint8_t CMD8 = 0X08; | |||
const uint8_t CMD9 = 0X09; | |||
/** SEND_CID - read the card identification information (CID register) */ | |||
const uint8_t CMD10 = 0X0A; | |||
/** VOLTAGE_SWITCH -Switch to 1.8V bus signaling level. */ | |||
const uint8_t CMD11 = 0X0B; | |||
/** STOP_TRANSMISSION - end multiple sector read sequence */ | |||
const uint8_t CMD12 = 0X0C; | |||
/** SEND_STATUS - read the card status register */ |
@@ -150,6 +150,8 @@ const uint32_t CMD9_XFERTYP = SDHC_XFERTYP_CMDINX(CMD9) | CMD_RESP_R2; | |||
const uint32_t CMD10_XFERTYP = SDHC_XFERTYP_CMDINX(CMD10) | CMD_RESP_R2; | |||
const uint32_t CMD11_XFERTYP = SDHC_XFERTYP_CMDINX(CMD11) | CMD_RESP_R1; | |||
const uint32_t CMD12_XFERTYP = SDHC_XFERTYP_CMDINX(CMD12) | CMD_RESP_R1b | | |||
SDHC_XFERTYP_CMDTYP(3); | |||