| @@ -1,11 +1,5 @@ | |||
| ### Warning: This beta is for testing with Particle IoT mesh devices. | |||
| This version of SdFat has been modified to use standard POSIX/Linux | |||
| definitions of open flags from fcntl.h. | |||
| Open flags are access modes, O_RDONLY, O_RDWR, O_WRONLY, and modifiers | |||
| O_APPEND, O_CREAT, O_EXCL, O_SYNC, O_TRUNC. | |||
| Rename this folder SdFat and place it in the standard place for libraries. | |||
| I tested with a particle CLI project with a SdFat in a lib | |||
| @@ -20,6 +14,33 @@ SdFat | |||
| src: | |||
| SdFatMod.ino | |||
| ``` | |||
| Changess Version 1.0.10: | |||
| Added custom Particle driver to use DMA and allow use of SPI1. | |||
| To use SPI1 declare SdFat/SdFatEX class like this: | |||
| ``` | |||
| SdFat sd1(&SPI1); | |||
| // or | |||
| SdFatEX sd1(&SPI1); | |||
| ``` | |||
| Changed STM32 use of SPI ports. See STM32Test example. | |||
| To use second SPI port: | |||
| ``` | |||
| // Use second SPI port | |||
| SPIClass SPI_2(2); | |||
| SdFat sd2(&SPI_2); | |||
| ``` | |||
| Changes Version 1.0.9: | |||
| This version of SdFat has been modified to use standard POSIX/Linux | |||
| definitions of open flags from fcntl.h. | |||
| Open flags are access modes, O_RDONLY, O_RDWR, O_WRONLY, and modifiers | |||
| O_APPEND, O_CREAT, O_EXCL, O_SYNC, O_TRUNC. | |||
| The mods required changing the type for open flags from uint8_t to int so | |||
| bugs are likely if any uint8_t local variables were missed. | |||
| @@ -9,13 +9,15 @@ | |||
| // set ENABLE_EXTENDED_TRANSFER_CLASS non-zero to use faster EX classes | |||
| // Use first SPI port | |||
| SdFat sd1(1); | |||
| // SdFatEX sd1(1); | |||
| SdFat sd1; | |||
| // SdFatEX sd1; | |||
| const uint8_t SD1_CS = PA4; // chip select for sd1 | |||
| // Use second SPI port | |||
| SdFat sd2(2); | |||
| // SdFatEX sd2(2); | |||
| SPIClass SPI_2(2); | |||
| SdFat sd2(&SPI_2); | |||
| // SdFatEX sd2(&SPI_2); | |||
| const uint8_t SD2_CS = PB12; // chip select for sd2 | |||
| const uint8_t BUF_DIM = 100; | |||
| @@ -170,4 +172,4 @@ void setup() { | |||
| Serial.println(F("Done")); | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| void loop() {} | |||
| void loop() {} | |||
| @@ -110,7 +110,7 @@ void loop() { | |||
| while (!Serial.available()) { | |||
| SysCall::yield(); | |||
| } | |||
| cout << F("chipSelect: ") << int(chipSelect) << endl; | |||
| cout << F("FreeStack: ") << FreeStack() << endl; | |||
| #if USE_SDIO | |||
| @@ -1,5 +1,5 @@ | |||
| /** | |||
| * Copyright (c) 20011-2017 Bill Greiman | |||
| * Copyright (c) 20011-2018 Bill Greiman | |||
| * This file is part of the SdFat library for SD memory cards. | |||
| * | |||
| * MIT License | |||
| @@ -24,7 +24,7 @@ | |||
| */ | |||
| /** | |||
| \mainpage Arduino %SdFat Library | |||
| <CENTER>Copyright © 2012, 2013, 2014, 2015, 2016 by William Greiman | |||
| <CENTER>Copyright © 2012-2018 by William Greiman | |||
| </CENTER> | |||
| \section Intro Introduction | |||
| @@ -1,5 +1,5 @@ | |||
| name=SdFat | |||
| version=1.0.9 | |||
| version=1.0.10 | |||
| author=Bill Greiman <fat16lib@sbcglobal.net> | |||
| maintainer=Bill Greiman <fat16lib@sbcglobal.net> | |||
| sentence=FAT16/FAT32 file system for SD cards. | |||
| @@ -505,36 +505,36 @@ bool FatFile::openCachedEntry(FatFile* dirFile, uint16_t dirIndex, | |||
| m_attr |= FILE_ATTR_FILE; | |||
| } | |||
| m_lfnOrd = lfnOrd; | |||
| switch(oflag & O_ACCMODE){ | |||
| switch (oflag & O_ACCMODE) { | |||
| case O_RDONLY: | |||
| if (oflag & O_TRUNC) { | |||
| DBG_FAIL_MACRO; | |||
| goto fail; | |||
| goto fail; | |||
| } | |||
| m_flags = F_READ; | |||
| break; | |||
| case O_RDWR: | |||
| m_flags = F_READ | F_WRITE; | |||
| break; | |||
| case O_WRONLY: | |||
| m_flags = F_WRITE; | |||
| m_flags = F_WRITE; | |||
| break; | |||
| default: | |||
| DBG_FAIL_MACRO; | |||
| goto fail; | |||
| } | |||
| if (m_flags & F_WRITE) { | |||
| if (isSubDir() || isReadOnly()) { | |||
| DBG_FAIL_MACRO; | |||
| goto fail; | |||
| } | |||
| } | |||
| m_flags |= (oflag & O_APPEND ? F_APPEND : 0) | (oflag & O_SYNC ? F_SYNC : 0); | |||
| m_dirBlock = m_vol->cacheBlockNumber(); | |||
| @@ -263,9 +263,9 @@ class FatVolume { | |||
| //------------------------------------------------------------------------------ | |||
| private: | |||
| // Allow FatFile and FatCache access to FatVolume private functions. | |||
| friend class FatCache; | |||
| friend class FatFile; | |||
| friend class FatFileSystem; | |||
| friend class FatCache; ///< Allow access to FatVolume. | |||
| friend class FatFile; ///< Allow access to FatVolume. | |||
| friend class FatFileSystem; ///< Allow access to FatVolume. | |||
| //------------------------------------------------------------------------------ | |||
| BlockDriver* m_blockDev; // block device | |||
| uint8_t m_blocksPerCluster; // Cluster size in blocks. | |||
| @@ -101,19 +101,19 @@ bool StdioStream::fopen(const char* path, const char* mode) { | |||
| case 'a': | |||
| m = O_WRONLY; | |||
| oflag = O_CREAT | O_APPEND; | |||
| m_status = S_SWR; | |||
| m_status = S_SWR; | |||
| break; | |||
| case 'r': | |||
| m = O_RDONLY; | |||
| oflag = 0; | |||
| m_status = S_SRD; | |||
| m_status = S_SRD; | |||
| break; | |||
| case 'w': | |||
| m = O_WRONLY; | |||
| oflag = O_CREAT | O_TRUNC; | |||
| m_status = S_SWR; | |||
| m_status = S_SWR; | |||
| break; | |||
| default: | |||
| @@ -236,28 +236,6 @@ int32_t StdioStream::ftell() { | |||
| //------------------------------------------------------------------------------ | |||
| size_t StdioStream::fwrite(const void* ptr, size_t size, size_t count) { | |||
| return write(ptr, count*size) < 0 ? EOF : count; | |||
| #if 0 //////////////////////////////////////////////////////////////////////////////////// | |||
| const uint8_t* src = static_cast<const uint8_t*>(ptr); | |||
| size_t total = count*size; | |||
| if (total == 0) { | |||
| return 0; | |||
| } | |||
| size_t todo = total; | |||
| while (todo > m_w) { | |||
| memcpy(m_p, src, m_w); | |||
| m_p += m_w; | |||
| src += m_w; | |||
| todo -= m_w; | |||
| if (!flushBuf()) { | |||
| return (total - todo)/size; | |||
| } | |||
| } | |||
| memcpy(m_p, src, todo); | |||
| m_p += todo; | |||
| m_w -= todo; | |||
| return count; | |||
| #endif ////////////////////////////////////////////////////////////////////////////////// | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| int StdioStream::write(const void* buf, size_t count) { | |||
| @@ -81,6 +81,7 @@ typedef enum { | |||
| SD_CARD_ERROR_WRITE, | |||
| SD_CARD_ERROR_WRITE_FIFO, | |||
| SD_CARD_ERROR_WRITE_START, | |||
| SD_CARD_ERROR_FLASH_PROGRAMMING, | |||
| SD_CARD_ERROR_WRITE_TIMEOUT, | |||
| // Misc errors. | |||
| @@ -124,9 +125,9 @@ const uint16_t SD_INIT_TIMEOUT = 2000; | |||
| /** erase timeout ms */ | |||
| const uint16_t SD_ERASE_TIMEOUT = 10000; | |||
| /** read timeout ms */ | |||
| const uint16_t SD_READ_TIMEOUT = 300; | |||
| const uint16_t SD_READ_TIMEOUT = 1000; | |||
| /** write time out ms */ | |||
| const uint16_t SD_WRITE_TIMEOUT = 600; | |||
| const uint16_t SD_WRITE_TIMEOUT = 2000; | |||
| //------------------------------------------------------------------------------ | |||
| // SD card commands | |||
| /** GO_IDLE_STATE - init card in spi mode if CS low */ | |||
| @@ -543,7 +543,7 @@ bool SdSpiCard::writeBlock(uint32_t blockNumber, const uint8_t* src) { | |||
| #if CHECK_FLASH_PROGRAMMING | |||
| // wait for flash programming to complete | |||
| if (!waitNotBusy(SD_WRITE_TIMEOUT)) { | |||
| error(SD_CARD_ERROR_WRITE_TIMEOUT); | |||
| error(SD_CARD_ERROR_FLASH_PROGRAMMING); | |||
| goto fail; | |||
| } | |||
| // response is r2 so get and check two bytes for nonzero | |||
| @@ -37,7 +37,7 @@ | |||
| #endif // INCLUDE_SDIOS | |||
| //------------------------------------------------------------------------------ | |||
| /** SdFat version */ | |||
| #define SD_FAT_VERSION "1.0.9" | |||
| #define SD_FAT_VERSION "1.0.10" | |||
| //============================================================================== | |||
| /** | |||
| * \class SdBaseFile | |||
| @@ -311,13 +311,13 @@ class SdFat : public SdFileSystem<SdSpiCard> { | |||
| public: | |||
| #if IMPLEMENT_SPI_PORT_SELECTION || defined(DOXYGEN) | |||
| SdFat() { | |||
| m_spi.setPortNumber(0); | |||
| m_spi.setPort(nullptr); | |||
| } | |||
| /** Constructor with SPI port selection. | |||
| * \param[in] spiPort SPI port number. | |||
| */ | |||
| explicit SdFat(uint8_t spiPort) { | |||
| m_spi.setPortNumber(spiPort); | |||
| explicit SdFat(SPIClass* spiPort) { | |||
| m_spi.setPort(spiPort); | |||
| } | |||
| #endif // IMPLEMENT_SPI_PORT_SELECTION | |||
| /** Initialize SD card and file system. | |||
| @@ -444,13 +444,13 @@ class SdFatEX : public SdFileSystem<SdSpiCardEX> { | |||
| public: | |||
| #if IMPLEMENT_SPI_PORT_SELECTION || defined(DOXYGEN) | |||
| SdFatEX() { | |||
| m_spi.setPortNumber(0); | |||
| m_spi.setPort(nullptr); | |||
| } | |||
| /** Constructor with SPI port selection. | |||
| * \param[in] spiPort SPI port number. | |||
| */ | |||
| explicit SdFatEX(uint8_t spiPort) { | |||
| m_spi.setPortNumber(spiPort); | |||
| explicit SdFatEX(SPIClass* spiPort) { | |||
| m_spi.setPort(spiPort); | |||
| } | |||
| #endif // IMPLEMENT_SPI_PORT_SELECTION | |||
| /** Initialize SD card and file system. | |||
| @@ -69,14 +69,16 @@ | |||
| * the SPI bus may not be shared with other devices in this mode. | |||
| */ | |||
| #define ENABLE_EXTENDED_TRANSFER_CLASS 0 | |||
| //----------------------------------------------------------------------------- | |||
| //------------------------------------------------------------------------------ | |||
| /** | |||
| * If the symbol USE_STANDARD_SPI_LIBRARY is nonzero, the classes SdFat and | |||
| * SdFatEX use the standard Arduino SPI.h library. If USE_STANDARD_SPI_LIBRARY | |||
| * is zero, an optimized custom SPI driver is used if it exists. | |||
| * If the symbol USE_STANDARD_SPI_LIBRARY is zero, an optimized custom SPI | |||
| * driver is used if it exists. If the symbol USE_STANDARD_SPI_LIBRARY is | |||
| * one, the standard Arduino SPI.h library is used with SPI. If the symbol | |||
| * USE_STANDARD_SPI_LIBRARY is two, the SPI port can be selected with the | |||
| * constructors SdFat(SPIClass* spiPort) and SdFatEX(SPIClass* spiPort). | |||
| */ | |||
| #define USE_STANDARD_SPI_LIBRARY 0 | |||
| //----------------------------------------------------------------------------- | |||
| //------------------------------------------------------------------------------ | |||
| /** | |||
| * If the symbol ENABLE_SOFTWARE_SPI_CLASS is nonzero, the class SdFatSoftSpi | |||
| * will be defined. If ENABLE_EXTENDED_TRANSFER_CLASS is also nonzero, | |||
| @@ -86,14 +88,14 @@ | |||
| //------------------------------------------------------------------------------ | |||
| /** If the symbol USE_FCNTL_H is nonzero, open flags for access modes O_RDONLY, | |||
| * O_WRONLY, O_RDWR and the open modifiers O_APPEND, O_CREAT, O_EXCL, O_SYNC | |||
| * will be defined by including the system file fcntl.h. | |||
| * will be defined by including the system file fcntl.h. | |||
| */ | |||
| #if defined(__AVR__) | |||
| // AVR fcntl.h does not define open flags. | |||
| #define USE_FCNTL_H 0 | |||
| #elif defined(PLATFORM_ID) | |||
| // Particle boards - use fcntl.h. | |||
| #define USE_FCNTL_H 1 | |||
| #define USE_FCNTL_H 1 | |||
| #elif defined(__arm__) | |||
| // ARM gcc defines open flags. | |||
| #define USE_FCNTL_H 1 | |||
| @@ -102,7 +104,7 @@ | |||
| #endif // defined(__AVR__) | |||
| //------------------------------------------------------------------------------ | |||
| /** | |||
| * If CHECK_FLASH_PROGRAMMING is zero, overlap of single sector flash | |||
| * If CHECK_FLASH_PROGRAMMING is zero, overlap of single sector flash | |||
| * programming and other operations will be allowed for faster write | |||
| * performance. | |||
| * | |||
| @@ -207,7 +209,7 @@ | |||
| /** | |||
| * Determine the default SPI configuration. | |||
| */ | |||
| #if defined(__STM32F1__) || defined(__STM32F4__) | |||
| #if defined(__STM32F1__) || defined(__STM32F4__) || defined(PLATFORM_ID) | |||
| // has multiple SPI ports | |||
| #define SD_HAS_CUSTOM_SPI 2 | |||
| #elif defined(__AVR__)\ | |||
| @@ -223,9 +225,9 @@ | |||
| /** | |||
| * Check if API to select HW SPI port is needed. | |||
| */ | |||
| #if (USE_STANDARD_SPI_LIBRARY || SD_HAS_CUSTOM_SPI < 2) | |||
| #define IMPLEMENT_SPI_PORT_SELECTION 0 | |||
| #else // USE_STANDARD_SPI_LIBRARY | |||
| #if USE_STANDARD_SPI_LIBRARY > 1 || SD_HAS_CUSTOM_SPI > 1 | |||
| #define IMPLEMENT_SPI_PORT_SELECTION 1 | |||
| #endif // USE_STANDARD_SPI_LIBRARY | |||
| #else // IMPLEMENT_SPI_PORT_SELECTION | |||
| #define IMPLEMENT_SPI_PORT_SELECTION 0 | |||
| #endif // IMPLEMENT_SPI_PORT_SELECTION | |||
| #endif // SdFatConfig_h | |||
| @@ -32,12 +32,12 @@ | |||
| #include "SPI.h" | |||
| #include "SdSpiBaseDriver.h" | |||
| #include "SdFatConfig.h" | |||
| //----------------------------------------------------------------------------- | |||
| //------------------------------------------------------------------------------ | |||
| /** SDCARD_SPI is defined if board has built-in SD card socket */ | |||
| #ifndef SDCARD_SPI | |||
| #define SDCARD_SPI SPI | |||
| #endif // SDCARD_SPI | |||
| //----------------------------------------------------------------------------- | |||
| //------------------------------------------------------------------------------ | |||
| /** | |||
| * \class SdSpiLibDriver | |||
| * \brief SdSpiLibDriver - use standard SPI library. | |||
| @@ -48,6 +48,63 @@ class SdSpiLibDriver : public SdSpiBaseDriver { | |||
| class SdSpiLibDriver { | |||
| #endif // ENABLE_SOFTWARE_SPI_CLASS | |||
| public: | |||
| #if IMPLEMENT_SPI_PORT_SELECTION | |||
| /** Activate SPI hardware. */ | |||
| void activate() { | |||
| m_spi->beginTransaction(m_spiSettings); | |||
| } | |||
| /** Deactivate SPI hardware. */ | |||
| void deactivate() { | |||
| m_spi->endTransaction(); | |||
| } | |||
| /** Initialize the SPI bus. | |||
| * | |||
| * \param[in] csPin SD card chip select pin. | |||
| */ | |||
| void begin(uint8_t csPin) { | |||
| m_csPin = csPin; | |||
| digitalWrite(csPin, HIGH); | |||
| pinMode(csPin, OUTPUT); | |||
| m_spi->begin(); | |||
| } | |||
| /** Receive a byte. | |||
| * | |||
| * \return The byte. | |||
| */ | |||
| uint8_t receive() { | |||
| return m_spi->transfer( 0XFF); | |||
| } | |||
| /** Receive multiple bytes. | |||
| * | |||
| * \param[out] buf Buffer to receive the data. | |||
| * \param[in] n Number of bytes to receive. | |||
| * | |||
| * \return Zero for no error or nonzero error code. | |||
| */ | |||
| uint8_t receive(uint8_t* buf, size_t n) { | |||
| for (size_t i = 0; i < n; i++) { | |||
| buf[i] = m_spi->transfer(0XFF); | |||
| } | |||
| return 0; | |||
| } | |||
| /** Send a byte. | |||
| * | |||
| * \param[in] data Byte to send | |||
| */ | |||
| void send(uint8_t data) { | |||
| m_spi->transfer(data); | |||
| } | |||
| /** Send multiple bytes. | |||
| * | |||
| * \param[in] buf Buffer for data to be sent. | |||
| * \param[in] n Number of bytes to send. | |||
| */ | |||
| void send(const uint8_t* buf, size_t n) { | |||
| for (size_t i = 0; i < n; i++) { | |||
| m_spi->transfer(buf[i]); | |||
| } | |||
| } | |||
| #else // IMPLEMENT_SPI_PORT_SELECTION | |||
| /** Activate SPI hardware. */ | |||
| void activate() { | |||
| SDCARD_SPI.beginTransaction(m_spiSettings); | |||
| @@ -103,6 +160,7 @@ class SdSpiLibDriver { | |||
| SDCARD_SPI.transfer(buf[i]); | |||
| } | |||
| } | |||
| #endif // IMPLEMENT_SPI_PORT_SELECTION | |||
| /** Set CS low. */ | |||
| void select() { | |||
| digitalWrite(m_csPin, LOW); | |||
| @@ -118,12 +176,22 @@ class SdSpiLibDriver { | |||
| void unselect() { | |||
| digitalWrite(m_csPin, HIGH); | |||
| } | |||
| #if IMPLEMENT_SPI_PORT_SELECTION || defined(DOXYGEN) | |||
| /** Set SPI port. | |||
| * \param[in] spiPort Hardware SPI port. | |||
| */ | |||
| void setPort(SPIClass* spiPort) { | |||
| m_spi = spiPort ? spiPort : &SDCARD_SPI; | |||
| } | |||
| private: | |||
| SPIClass* m_spi; | |||
| #else // IMPLEMENT_SPI_PORT_SELECTION | |||
| private: | |||
| #endif // IMPLEMENT_SPI_PORT_SELECTION | |||
| SPISettings m_spiSettings; | |||
| uint8_t m_csPin; | |||
| }; | |||
| //----------------------------------------------------------------------------- | |||
| //------------------------------------------------------------------------------ | |||
| /** | |||
| * \class SdSpiAltDriver | |||
| * \brief Optimized SPI class for access to SD and SDHC flash memory cards. | |||
| @@ -184,9 +252,11 @@ class SdSpiAltDriver { | |||
| } | |||
| #if IMPLEMENT_SPI_PORT_SELECTION || defined(DOXYGEN) | |||
| /** Set SPI port number. | |||
| * \param[in] portNumber Hardware SPI port number. | |||
| * \param[in] spiPort Hardware SPI port. | |||
| */ | |||
| void setPortNumber(uint8_t portNumber); | |||
| void setPort(SPIClass* spiPort) { | |||
| m_spi = spiPort ? spiPort : &SDCARD_SPI; | |||
| } | |||
| private: | |||
| SPIClass* m_spi; | |||
| #else // IMPLEMENT_SPI_PORT_SELECTION | |||
| @@ -281,7 +351,7 @@ class SdSpiSoftDriver : public SdSpiBaseDriver { | |||
| SoftSPI<MisoPin, MosiPin, SckPin, 0> m_spi; | |||
| }; | |||
| #endif // ENABLE_SOFTWARE_SPI_CLASS || defined(DOXYGEN) | |||
| //----------------------------------------------------------------------------- | |||
| //------------------------------------------------------------------------------ | |||
| // Choose SPI driver for SdFat and SdFatEX classes. | |||
| #if USE_STANDARD_SPI_LIBRARY || !SD_HAS_CUSTOM_SPI | |||
| /** SdFat uses Arduino library SPI. */ | |||
| @@ -299,7 +369,7 @@ typedef SdSpiBaseDriver SdSpiDriver; | |||
| // Don't need virtual driver. | |||
| typedef SdFatSpiDriver SdSpiDriver; | |||
| #endif // ENABLE_SOFTWARE_SPI_CLASS | |||
| //============================================================================= | |||
| //============================================================================== | |||
| // Use of in-line for AVR to save flash. | |||
| #ifdef __AVR__ | |||
| //------------------------------------------------------------------------------ | |||
| @@ -0,0 +1,102 @@ | |||
| /** | |||
| * Copyright (c) 2011-2018 Bill Greiman | |||
| * This file is part of the SdFat library for SD memory cards. | |||
| * | |||
| * MIT License | |||
| * | |||
| * Permission is hereby granted, free of charge, to any person obtaining a | |||
| * copy of this software and associated documentation files (the "Software"), | |||
| * to deal in the Software without restriction, including without limitation | |||
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||
| * and/or sell copies of the Software, and to permit persons to whom the | |||
| * Software is furnished to do so, subject to the following conditions: | |||
| * | |||
| * The above copyright notice and this permission notice shall be included | |||
| * in all copies or substantial portions of the Software. | |||
| * | |||
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
| * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||
| * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| * DEALINGS IN THE SOFTWARE. | |||
| */ | |||
| #if defined(PLATFORM_ID) | |||
| #include "SdSpiDriver.h" | |||
| static volatile bool SPI_DMA_TransferCompleted = false; | |||
| //----------------------------------------------------------------------------- | |||
| static void SD_SPI_DMA_TransferComplete_Callback(void) { | |||
| SPI_DMA_TransferCompleted = true; | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| /** Set SPI options for access to SD/SDHC cards. | |||
| * | |||
| * \param[in] divisor SCK clock divider relative to the APB1 or APB2 clock. | |||
| */ | |||
| void SdSpiAltDriver::activate() { | |||
| m_spi->beginTransaction(m_spiSettings); | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| /** Initialize the SPI bus. | |||
| * | |||
| * \param[in] chipSelectPin SD card chip select pin. | |||
| */ | |||
| void SdSpiAltDriver::begin(uint8_t csPin) { | |||
| m_csPin = csPin; | |||
| pinMode(m_csPin, OUTPUT); | |||
| digitalWrite(m_csPin, HIGH); | |||
| m_spi->begin(); | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| /** | |||
| * End SPI transaction. | |||
| */ | |||
| void SdSpiAltDriver::deactivate() { | |||
| m_spi->endTransaction(); | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| /** Receive a byte. | |||
| * | |||
| * \return The byte. | |||
| */ | |||
| uint8_t SdSpiAltDriver::receive() { | |||
| return m_spi->transfer(0XFF); | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| /** Receive multiple bytes. | |||
| * | |||
| * \param[out] buf Buffer to receive the data. | |||
| * \param[in] n Number of bytes to receive. | |||
| * | |||
| * \return Zero for no error or nonzero error code. | |||
| */ | |||
| uint8_t SdSpiAltDriver::receive(uint8_t* buf, size_t n) { | |||
| SPI_DMA_TransferCompleted = false; | |||
| m_spi->transfer(0, buf, n, SD_SPI_DMA_TransferComplete_Callback); | |||
| while (!SPI_DMA_TransferCompleted) {} | |||
| return 0; | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| /** Send a byte. | |||
| * | |||
| * \param[in] b Byte to send | |||
| */ | |||
| void SdSpiAltDriver::send(uint8_t b) { | |||
| m_spi->transfer(b); | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| /** Send multiple bytes. | |||
| * | |||
| * \param[in] buf Buffer for data to be sent. | |||
| * \param[in] n Number of bytes to send. | |||
| */ | |||
| void SdSpiAltDriver::send(const uint8_t* buf , size_t n) { | |||
| SPI_DMA_TransferCompleted = false; | |||
| m_spi->transfer(const_cast<uint8_t*>(buf), 0, n, | |||
| SD_SPI_DMA_TransferComplete_Callback); | |||
| while (!SPI_DMA_TransferCompleted) {} | |||
| } | |||
| #endif // defined(PLATFORM_ID) | |||
| @@ -167,7 +167,7 @@ uint8_t SdSpiAltDriver::receive(uint8_t* buf, size_t n) { | |||
| int rtn = 0; | |||
| #if USE_SAM3X_DMAC | |||
| // clear overrun error | |||
| uint32_t s = pSpi->SPI_SR; | |||
| pSpi->SPI_SR; | |||
| spiDmaRX(buf, n); | |||
| spiDmaTX(0, n); | |||
| @@ -213,6 +213,6 @@ void SdSpiAltDriver::send(const uint8_t* buf , size_t n) { | |||
| #endif // #if USE_SAM3X_DMAC | |||
| while ((pSpi->SPI_SR & SPI_SR_TXEMPTY) == 0) {} | |||
| // leave RDR empty | |||
| uint8_t b = pSpi->SPI_RDR; | |||
| pSpi->SPI_RDR; | |||
| } | |||
| #endif // defined(__SAM3X8E__) || defined(__SAM3X8H__) | |||
| @@ -32,17 +32,6 @@ | |||
| #error Unknown STM32 type | |||
| #endif // defined(__STM32F1__) | |||
| //------------------------------------------------------------------------------ | |||
| static SPIClass m_SPI1(1); | |||
| #if BOARD_NR_SPI >= 2 | |||
| static SPIClass m_SPI2(2); | |||
| #endif // BOARD_NR_SPI >= 2 | |||
| #if BOARD_NR_SPI >= 3 | |||
| static SPIClass m_SPI3(3); | |||
| #endif // BOARD_NR_SPI >= 3 | |||
| #if BOARD_NR_SPI > 3 | |||
| #error BOARD_NR_SPI too large | |||
| #endif | |||
| //------------------------------------------------------------------------------ | |||
| /** Set SPI options for access to SD/SDHC cards. | |||
| * | |||
| * \param[in] divisor SCK clock divider relative to the APB1 or APB2 clock. | |||
| @@ -113,18 +102,4 @@ void SdSpiAltDriver::send(const uint8_t* buf , size_t n) { | |||
| m_spi->write(const_cast<uint8*>(buf), n); | |||
| #endif // USE_STM32_DMA | |||
| } | |||
| //------------------------------------------------------------------------------ | |||
| void SdSpiAltDriver::setPortNumber(uint8_t portNumber) { | |||
| m_spi = &m_SPI1; | |||
| #if BOARD_NR_SPI >= 2 | |||
| if (portNumber == 2) { | |||
| m_spi = &m_SPI2; | |||
| } | |||
| #endif // BOARD_NR_SPI >= 2 | |||
| #if BOARD_NR_SPI >= 3 | |||
| if (portNumber == 3) { | |||
| m_spi = &m_SPI3; | |||
| } | |||
| #endif // BOARD_NR_SPI >= 2 | |||
| } | |||
| #endif // defined(__STM32F1__) || defined(__STM32F4__) | |||