Browse Source

Add new Partiicle IoT driver

main
Bill Greiman 6 years ago
parent
commit
1f87c86fed
16 changed files with 261 additions and 110 deletions
  1. +27
    -6
      README.md
  2. +7
    -5
      examples/STM32Test/STM32Test.ino
  3. +1
    -1
      examples/bench/bench.ino
  4. +2
    -2
      extras/MainPage/SdFatmainpage.h
  5. +1
    -1
      library.properties
  6. +9
    -9
      src/FatLib/FatFile.cpp
  7. +3
    -3
      src/FatLib/FatVolume.h
  8. +3
    -25
      src/FatLib/StdioStream.cpp
  9. +3
    -2
      src/SdCard/SdInfo.h
  10. +1
    -1
      src/SdCard/SdSpiCard.cpp
  11. +7
    -7
      src/SdFat.h
  12. +15
    -13
      src/SdFatConfig.h
  13. +78
    -8
      src/SpiDriver/SdSpiDriver.h
  14. +102
    -0
      src/SpiDriver/SdSpiParticle.cpp
  15. +2
    -2
      src/SpiDriver/SdSpiSAM3X.cpp
  16. +0
    -25
      src/SpiDriver/SdSpiSTM32.cpp

+ 27
- 6
README.md View File

### Warning: This beta is for testing with Particle IoT mesh devices. ### 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. 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 I tested with a particle CLI project with a SdFat in a lib
src: src:
SdFatMod.ino 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 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. bugs are likely if any uint8_t local variables were missed.

+ 7
- 5
examples/STM32Test/STM32Test.ino View File

// set ENABLE_EXTENDED_TRANSFER_CLASS non-zero to use faster EX classes // set ENABLE_EXTENDED_TRANSFER_CLASS non-zero to use faster EX classes


// Use first SPI port // Use first SPI port
SdFat sd1(1);
// SdFatEX sd1(1);
SdFat sd1;
// SdFatEX sd1;
const uint8_t SD1_CS = PA4; // chip select for sd1 const uint8_t SD1_CS = PA4; // chip select for sd1


// Use second SPI port // 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 SD2_CS = PB12; // chip select for sd2


const uint8_t BUF_DIM = 100; const uint8_t BUF_DIM = 100;
Serial.println(F("Done")); Serial.println(F("Done"));
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void loop() {}
void loop() {}

+ 1
- 1
examples/bench/bench.ino View File

while (!Serial.available()) { while (!Serial.available()) {
SysCall::yield(); SysCall::yield();
} }
cout << F("chipSelect: ") << int(chipSelect) << endl;
cout << F("FreeStack: ") << FreeStack() << endl; cout << F("FreeStack: ") << FreeStack() << endl;


#if USE_SDIO #if USE_SDIO

+ 2
- 2
extras/MainPage/SdFatmainpage.h View File

/** /**
* Copyright (c) 20011-2017 Bill Greiman
* Copyright (c) 20011-2018 Bill Greiman
* This file is part of the SdFat library for SD memory cards. * This file is part of the SdFat library for SD memory cards.
* *
* MIT License * MIT License
*/ */
/** /**
\mainpage Arduino %SdFat Library \mainpage Arduino %SdFat Library
<CENTER>Copyright &copy; 2012, 2013, 2014, 2015, 2016 by William Greiman
<CENTER>Copyright &copy 2012-2018 by William Greiman
</CENTER> </CENTER>


\section Intro Introduction \section Intro Introduction

+ 1
- 1
library.properties View File

name=SdFat name=SdFat
version=1.0.9
version=1.0.10
author=Bill Greiman <fat16lib@sbcglobal.net> author=Bill Greiman <fat16lib@sbcglobal.net>
maintainer=Bill Greiman <fat16lib@sbcglobal.net> maintainer=Bill Greiman <fat16lib@sbcglobal.net>
sentence=FAT16/FAT32 file system for SD cards. sentence=FAT16/FAT32 file system for SD cards.

+ 9
- 9
src/FatLib/FatFile.cpp View File

m_attr |= FILE_ATTR_FILE; m_attr |= FILE_ATTR_FILE;
} }
m_lfnOrd = lfnOrd; m_lfnOrd = lfnOrd;
switch(oflag & O_ACCMODE){
switch (oflag & O_ACCMODE) {
case O_RDONLY: case O_RDONLY:
if (oflag & O_TRUNC) { if (oflag & O_TRUNC) {
DBG_FAIL_MACRO; DBG_FAIL_MACRO;
goto fail;
goto fail;
} }
m_flags = F_READ; m_flags = F_READ;
break; break;
case O_RDWR: case O_RDWR:
m_flags = F_READ | F_WRITE; m_flags = F_READ | F_WRITE;
break; break;
case O_WRONLY: case O_WRONLY:
m_flags = F_WRITE;
m_flags = F_WRITE;
break; break;
default: default:
DBG_FAIL_MACRO; DBG_FAIL_MACRO;
goto fail; goto fail;
} }
if (m_flags & F_WRITE) { if (m_flags & F_WRITE) {
if (isSubDir() || isReadOnly()) { if (isSubDir() || isReadOnly()) {
DBG_FAIL_MACRO; DBG_FAIL_MACRO;
goto fail; goto fail;
} }
} }
m_flags |= (oflag & O_APPEND ? F_APPEND : 0) | (oflag & O_SYNC ? F_SYNC : 0); m_flags |= (oflag & O_APPEND ? F_APPEND : 0) | (oflag & O_SYNC ? F_SYNC : 0);


m_dirBlock = m_vol->cacheBlockNumber(); m_dirBlock = m_vol->cacheBlockNumber();

+ 3
- 3
src/FatLib/FatVolume.h View File

//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
private: private:
// Allow FatFile and FatCache access to FatVolume private functions. // 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 BlockDriver* m_blockDev; // block device
uint8_t m_blocksPerCluster; // Cluster size in blocks. uint8_t m_blocksPerCluster; // Cluster size in blocks.

+ 3
- 25
src/FatLib/StdioStream.cpp View File

case 'a': case 'a':
m = O_WRONLY; m = O_WRONLY;
oflag = O_CREAT | O_APPEND; oflag = O_CREAT | O_APPEND;
m_status = S_SWR;
m_status = S_SWR;
break; break;


case 'r': case 'r':
m = O_RDONLY; m = O_RDONLY;
oflag = 0; oflag = 0;
m_status = S_SRD;
m_status = S_SRD;
break; break;


case 'w': case 'w':
m = O_WRONLY; m = O_WRONLY;
oflag = O_CREAT | O_TRUNC; oflag = O_CREAT | O_TRUNC;
m_status = S_SWR;
m_status = S_SWR;
break; break;


default: default:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
size_t StdioStream::fwrite(const void* ptr, size_t size, size_t count) { size_t StdioStream::fwrite(const void* ptr, size_t size, size_t count) {
return write(ptr, count*size) < 0 ? EOF : 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) { int StdioStream::write(const void* buf, size_t count) {

+ 3
- 2
src/SdCard/SdInfo.h View File

SD_CARD_ERROR_WRITE, SD_CARD_ERROR_WRITE,
SD_CARD_ERROR_WRITE_FIFO, SD_CARD_ERROR_WRITE_FIFO,
SD_CARD_ERROR_WRITE_START, SD_CARD_ERROR_WRITE_START,
SD_CARD_ERROR_FLASH_PROGRAMMING,
SD_CARD_ERROR_WRITE_TIMEOUT, SD_CARD_ERROR_WRITE_TIMEOUT,


// Misc errors. // Misc errors.
/** erase timeout ms */ /** erase timeout ms */
const uint16_t SD_ERASE_TIMEOUT = 10000; const uint16_t SD_ERASE_TIMEOUT = 10000;
/** read timeout ms */ /** read timeout ms */
const uint16_t SD_READ_TIMEOUT = 300;
const uint16_t SD_READ_TIMEOUT = 1000;
/** write time out ms */ /** write time out ms */
const uint16_t SD_WRITE_TIMEOUT = 600;
const uint16_t SD_WRITE_TIMEOUT = 2000;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// SD card commands // SD card commands
/** GO_IDLE_STATE - init card in spi mode if CS low */ /** GO_IDLE_STATE - init card in spi mode if CS low */

+ 1
- 1
src/SdCard/SdSpiCard.cpp View File

#if CHECK_FLASH_PROGRAMMING #if CHECK_FLASH_PROGRAMMING
// wait for flash programming to complete // wait for flash programming to complete
if (!waitNotBusy(SD_WRITE_TIMEOUT)) { if (!waitNotBusy(SD_WRITE_TIMEOUT)) {
error(SD_CARD_ERROR_WRITE_TIMEOUT);
error(SD_CARD_ERROR_FLASH_PROGRAMMING);
goto fail; goto fail;
} }
// response is r2 so get and check two bytes for nonzero // response is r2 so get and check two bytes for nonzero

+ 7
- 7
src/SdFat.h View File

#endif // INCLUDE_SDIOS #endif // INCLUDE_SDIOS
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** SdFat version */ /** SdFat version */
#define SD_FAT_VERSION "1.0.9"
#define SD_FAT_VERSION "1.0.10"
//============================================================================== //==============================================================================
/** /**
* \class SdBaseFile * \class SdBaseFile
public: public:
#if IMPLEMENT_SPI_PORT_SELECTION || defined(DOXYGEN) #if IMPLEMENT_SPI_PORT_SELECTION || defined(DOXYGEN)
SdFat() { SdFat() {
m_spi.setPortNumber(0);
m_spi.setPort(nullptr);
} }
/** Constructor with SPI port selection. /** Constructor with SPI port selection.
* \param[in] spiPort SPI port number. * \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 #endif // IMPLEMENT_SPI_PORT_SELECTION
/** Initialize SD card and file system. /** Initialize SD card and file system.
public: public:
#if IMPLEMENT_SPI_PORT_SELECTION || defined(DOXYGEN) #if IMPLEMENT_SPI_PORT_SELECTION || defined(DOXYGEN)
SdFatEX() { SdFatEX() {
m_spi.setPortNumber(0);
m_spi.setPort(nullptr);
} }
/** Constructor with SPI port selection. /** Constructor with SPI port selection.
* \param[in] spiPort SPI port number. * \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 #endif // IMPLEMENT_SPI_PORT_SELECTION
/** Initialize SD card and file system. /** Initialize SD card and file system.

+ 15
- 13
src/SdFatConfig.h View File

* the SPI bus may not be shared with other devices in this mode. * the SPI bus may not be shared with other devices in this mode.
*/ */
#define ENABLE_EXTENDED_TRANSFER_CLASS 0 #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 #define USE_STANDARD_SPI_LIBRARY 0
//-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
/** /**
* If the symbol ENABLE_SOFTWARE_SPI_CLASS is nonzero, the class SdFatSoftSpi * If the symbol ENABLE_SOFTWARE_SPI_CLASS is nonzero, the class SdFatSoftSpi
* will be defined. If ENABLE_EXTENDED_TRANSFER_CLASS is also nonzero, * will be defined. If ENABLE_EXTENDED_TRANSFER_CLASS is also nonzero,
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** If the symbol USE_FCNTL_H is nonzero, open flags for access modes O_RDONLY, /** 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 * 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__) #if defined(__AVR__)
// AVR fcntl.h does not define open flags. // AVR fcntl.h does not define open flags.
#define USE_FCNTL_H 0 #define USE_FCNTL_H 0
#elif defined(PLATFORM_ID) #elif defined(PLATFORM_ID)
// Particle boards - use fcntl.h. // Particle boards - use fcntl.h.
#define USE_FCNTL_H 1
#define USE_FCNTL_H 1
#elif defined(__arm__) #elif defined(__arm__)
// ARM gcc defines open flags. // ARM gcc defines open flags.
#define USE_FCNTL_H 1 #define USE_FCNTL_H 1
#endif // defined(__AVR__) #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 * programming and other operations will be allowed for faster write
* performance. * performance.
* *
/** /**
* Determine the default SPI configuration. * Determine the default SPI configuration.
*/ */
#if defined(__STM32F1__) || defined(__STM32F4__)
#if defined(__STM32F1__) || defined(__STM32F4__) || defined(PLATFORM_ID)
// has multiple SPI ports // has multiple SPI ports
#define SD_HAS_CUSTOM_SPI 2 #define SD_HAS_CUSTOM_SPI 2
#elif defined(__AVR__)\ #elif defined(__AVR__)\
/** /**
* Check if API to select HW SPI port is needed. * 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 #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 #endif // SdFatConfig_h

+ 78
- 8
src/SpiDriver/SdSpiDriver.h View File

#include "SPI.h" #include "SPI.h"
#include "SdSpiBaseDriver.h" #include "SdSpiBaseDriver.h"
#include "SdFatConfig.h" #include "SdFatConfig.h"
//-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
/** SDCARD_SPI is defined if board has built-in SD card socket */ /** SDCARD_SPI is defined if board has built-in SD card socket */
#ifndef SDCARD_SPI #ifndef SDCARD_SPI
#define SDCARD_SPI SPI #define SDCARD_SPI SPI
#endif // SDCARD_SPI #endif // SDCARD_SPI
//-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
/** /**
* \class SdSpiLibDriver * \class SdSpiLibDriver
* \brief SdSpiLibDriver - use standard SPI library. * \brief SdSpiLibDriver - use standard SPI library.
class SdSpiLibDriver { class SdSpiLibDriver {
#endif // ENABLE_SOFTWARE_SPI_CLASS #endif // ENABLE_SOFTWARE_SPI_CLASS
public: 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. */ /** Activate SPI hardware. */
void activate() { void activate() {
SDCARD_SPI.beginTransaction(m_spiSettings); SDCARD_SPI.beginTransaction(m_spiSettings);
SDCARD_SPI.transfer(buf[i]); SDCARD_SPI.transfer(buf[i]);
} }
} }
#endif // IMPLEMENT_SPI_PORT_SELECTION
/** Set CS low. */ /** Set CS low. */
void select() { void select() {
digitalWrite(m_csPin, LOW); digitalWrite(m_csPin, LOW);
void unselect() { void unselect() {
digitalWrite(m_csPin, HIGH); 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: private:
SPIClass* m_spi;
#else // IMPLEMENT_SPI_PORT_SELECTION
private:
#endif // IMPLEMENT_SPI_PORT_SELECTION
SPISettings m_spiSettings; SPISettings m_spiSettings;
uint8_t m_csPin; uint8_t m_csPin;
}; };
//-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
/** /**
* \class SdSpiAltDriver * \class SdSpiAltDriver
* \brief Optimized SPI class for access to SD and SDHC flash memory cards. * \brief Optimized SPI class for access to SD and SDHC flash memory cards.
} }
#if IMPLEMENT_SPI_PORT_SELECTION || defined(DOXYGEN) #if IMPLEMENT_SPI_PORT_SELECTION || defined(DOXYGEN)
/** Set SPI port number. /** 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: private:
SPIClass* m_spi; SPIClass* m_spi;
#else // IMPLEMENT_SPI_PORT_SELECTION #else // IMPLEMENT_SPI_PORT_SELECTION
SoftSPI<MisoPin, MosiPin, SckPin, 0> m_spi; SoftSPI<MisoPin, MosiPin, SckPin, 0> m_spi;
}; };
#endif // ENABLE_SOFTWARE_SPI_CLASS || defined(DOXYGEN) #endif // ENABLE_SOFTWARE_SPI_CLASS || defined(DOXYGEN)
//-----------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Choose SPI driver for SdFat and SdFatEX classes. // Choose SPI driver for SdFat and SdFatEX classes.
#if USE_STANDARD_SPI_LIBRARY || !SD_HAS_CUSTOM_SPI #if USE_STANDARD_SPI_LIBRARY || !SD_HAS_CUSTOM_SPI
/** SdFat uses Arduino library SPI. */ /** SdFat uses Arduino library SPI. */
// Don't need virtual driver. // Don't need virtual driver.
typedef SdFatSpiDriver SdSpiDriver; typedef SdFatSpiDriver SdSpiDriver;
#endif // ENABLE_SOFTWARE_SPI_CLASS #endif // ENABLE_SOFTWARE_SPI_CLASS
//=============================================================================
//==============================================================================
// Use of in-line for AVR to save flash. // Use of in-line for AVR to save flash.
#ifdef __AVR__ #ifdef __AVR__
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

+ 102
- 0
src/SpiDriver/SdSpiParticle.cpp View File

/**
* 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)

+ 2
- 2
src/SpiDriver/SdSpiSAM3X.cpp View File

int rtn = 0; int rtn = 0;
#if USE_SAM3X_DMAC #if USE_SAM3X_DMAC
// clear overrun error // clear overrun error
uint32_t s = pSpi->SPI_SR;
pSpi->SPI_SR;


spiDmaRX(buf, n); spiDmaRX(buf, n);
spiDmaTX(0, n); spiDmaTX(0, n);
#endif // #if USE_SAM3X_DMAC #endif // #if USE_SAM3X_DMAC
while ((pSpi->SPI_SR & SPI_SR_TXEMPTY) == 0) {} while ((pSpi->SPI_SR & SPI_SR_TXEMPTY) == 0) {}
// leave RDR empty // leave RDR empty
uint8_t b = pSpi->SPI_RDR;
pSpi->SPI_RDR;
} }
#endif // defined(__SAM3X8E__) || defined(__SAM3X8H__) #endif // defined(__SAM3X8E__) || defined(__SAM3X8H__)

+ 0
- 25
src/SpiDriver/SdSpiSTM32.cpp View File

#error Unknown STM32 type #error Unknown STM32 type
#endif // defined(__STM32F1__) #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. /** Set SPI options for access to SD/SDHC cards.
* *
* \param[in] divisor SCK clock divider relative to the APB1 or APB2 clock. * \param[in] divisor SCK clock divider relative to the APB1 or APB2 clock.
m_spi->write(const_cast<uint8*>(buf), n); m_spi->write(const_cast<uint8*>(buf), n);
#endif // USE_STM32_DMA #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__) #endif // defined(__STM32F1__) || defined(__STM32F4__)

Loading…
Cancel
Save