| @@ -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); | |||