/** * Copyright (c) 2011-2022 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. */ /** * \file * \brief SpiDriver classes */ #ifndef SdSpiDriver_h #define SdSpiDriver_h #include "../common/SysCall.h" /** * Initialize SD chip select pin. * * \param[in] pin SD card chip select pin. */ void sdCsInit(SdCsPin_t pin); /** * Initialize SD chip select pin. * * \param[in] pin SD card chip select pin. * \param[in] level SD card chip select level. */ void sdCsWrite(SdCsPin_t pin, bool level); //------------------------------------------------------------------------------ /** SPI bus is share with other devices. */ const uint8_t SHARED_SPI = 0; #if ENABLE_DEDICATED_SPI /** The SD is the only device on the SPI bus. */ const uint8_t DEDICATED_SPI = 1; /** * \param[in] opt option field of SdSpiConfig. * \return true for dedicated SPI. */ inline bool spiOptionDedicated(uint8_t opt) { return opt & DEDICATED_SPI; } #else // ENABLE_DEDICATED_SPI /** * \param[in] opt option field of SdSpiConfig. * \return true for dedicated SPI. */ inline bool spiOptionDedicated(uint8_t opt) { (void)opt; return false; } #endif // ENABLE_DEDICATED_SPI /** The user will call begin. Useful for custom SPI configurations. */ const uint8_t USER_SPI_BEGIN = 2; //------------------------------------------------------------------------------ /** SPISettings for SCK frequency in Hz. */ #define SD_SCK_HZ(maxSpeed) (maxSpeed) /** SPISettings for SCK frequency in MHz. */ #define SD_SCK_MHZ(maxMhz) (1000000UL * (maxMhz)) // SPI divisor constants - obsolete. /** Set SCK to max rate. */ #define SPI_FULL_SPEED SD_SCK_MHZ(50) /** Set SCK rate to 16 MHz for Due */ #define SPI_DIV3_SPEED SD_SCK_MHZ(16) /** Set SCK rate to 4 MHz for AVR. */ #define SPI_HALF_SPEED SD_SCK_MHZ(4) /** Set SCK rate to 8 MHz for Due */ #define SPI_DIV6_SPEED SD_SCK_MHZ(8) /** Set SCK rate to 2 MHz for AVR. */ #define SPI_QUARTER_SPEED SD_SCK_MHZ(2) /** Set SCK rate to 1 MHz for AVR. */ #define SPI_EIGHTH_SPEED SD_SCK_MHZ(1) /** Set SCK rate to 500 kHz for AVR. */ #define SPI_SIXTEENTH_SPEED SD_SCK_HZ(500000) //------------------------------------------------------------------------------ #if SPI_DRIVER_SELECT < 2 #include "SPI.h" /** Port type for Arduino SPI hardware driver. */ typedef SPIClass SpiPort_t; #elif SPI_DRIVER_SELECT == 2 class SdSpiSoftDriver; /** Port type for software SPI driver. */ typedef SdSpiSoftDriver SpiPort_t; #elif SPI_DRIVER_SELECT == 3 class SdSpiBaseClass; /** Port type for extrernal SPI driver. */ typedef SdSpiBaseClass SpiPort_t; #else // SPI_DRIVER_SELECT typedef void* SpiPort_t; #endif // SPI_DRIVER_SELECT //------------------------------------------------------------------------------ /** * \class SdSpiConfig * \brief SPI card configuration. */ class SdSpiConfig { public: /** SdSpiConfig constructor. * * \param[in] cs Chip select pin. * \param[in] opt Options. * \param[in] maxSpeed Maximum SCK frequency. * \param[in] port The SPI port to use. */ SdSpiConfig(SdCsPin_t cs, uint8_t opt, uint32_t maxSpeed, SpiPort_t* port) : csPin(cs), options(opt), maxSck(maxSpeed), spiPort(port) {} /** SdSpiConfig constructor. * * \param[in] cs Chip select pin. * \param[in] opt Options. * \param[in] maxSpeed Maximum SCK frequency. */ SdSpiConfig(SdCsPin_t cs, uint8_t opt, uint32_t maxSpeed) : csPin(cs), options(opt), maxSck(maxSpeed) {} /** SdSpiConfig constructor. * * \param[in] cs Chip select pin. * \param[in] opt Options. */ SdSpiConfig(SdCsPin_t cs, uint8_t opt) : csPin(cs), options(opt) {} /** SdSpiConfig constructor. * * \param[in] cs Chip select pin. */ explicit SdSpiConfig(SdCsPin_t cs) : csPin(cs) {} /** Chip select pin. */ const SdCsPin_t csPin; /** Options */ const uint8_t options = SHARED_SPI; /** Max SCK frequency */ const uint32_t maxSck = SD_SCK_MHZ(50); /** SPI port */ SpiPort_t* spiPort = nullptr; }; #if SPI_DRIVER_SELECT < 2 #include "SdSpiArduinoDriver.h" #elif SPI_DRIVER_SELECT == 2 #include "SdSpiSoftDriver.h" #elif SPI_DRIVER_SELECT == 3 #include "SdSpiBaseClass.h" typedef SdSpiBaseClass SdSpiDriver; #else // SPI_DRIVER_SELECT #error Invalid SPI_DRIVER_SELECT #endif // SPI_DRIVER_SELECT #endif // SdSpiDriver_h