|
-
-
- #ifndef SdSpi_h
- #define SdSpi_h
- #include <Arduino.h>
- #include "SdFatConfig.h"
- #include "utility/SoftSPI.h"
-
-
- class SdSpiBase {
- public:
-
- virtual void begin() = 0;
-
-
- virtual void init(uint8_t divisor);
-
-
- virtual uint8_t receive() = 0;
-
-
- virtual uint8_t receive(uint8_t* buf, size_t n) = 0;
-
-
- virtual void send(uint8_t data) = 0;
-
-
- virtual void send(const uint8_t* buf, size_t n) = 0;
-
- virtual bool useSpiTransactions() = 0;
- };
-
-
- #if SD_SPI_CONFIGURATION >= 3
- class SdSpi : public SdSpiBase {
- #else
- class SdSpi {
- #endif
- public:
-
- void begin();
-
-
- void init(uint8_t divisor);
-
-
- uint8_t receive();
-
-
- uint8_t receive(uint8_t* buf, size_t n);
-
-
- void send(uint8_t data);
-
-
- void send(const uint8_t* buf, size_t n);
-
- bool useSpiTransactions() {
- return true;
- }
- };
-
-
- #if SD_SPI_CONFIGURATION >= 3 || SD_SPI_CONFIGURATION == 1 || defined(DOXYGEN)
- #include <SPI.h>
- #if SD_SPI_CONFIGURATION >= 3
- class SdSpiLib : public SdSpiBase {
- #else
- class SdSpiLib {
- #endif
- public:
-
-
- void begin() {
- SPI.begin();
- }
-
-
- void init(uint8_t divisor) {
- SPI.setBitOrder(MSBFIRST);
- SPI.setDataMode(SPI_MODE0);
- #ifndef SPI_CLOCK_DIV128
- SPI.setClockDivider(divisor);
- #else
- int v;
- if (divisor <= 2) {
- v = SPI_CLOCK_DIV2;
- } else if (divisor <= 4) {
- v = SPI_CLOCK_DIV4;
- } else if (divisor <= 8) {
- v = SPI_CLOCK_DIV8;
- } else if (divisor <= 16) {
- v = SPI_CLOCK_DIV16;
- } else if (divisor <= 32) {
- v = SPI_CLOCK_DIV32;
- } else if (divisor <= 64) {
- v = SPI_CLOCK_DIV64;
- } else {
- v = SPI_CLOCK_DIV128;
- }
- SPI.setClockDivider(v);
- #endif
- }
-
-
- uint8_t receive() {
- return SPI.transfer(0XFF);
- }
-
-
- uint8_t receive(uint8_t* buf, size_t n) {
- for (size_t i = 0; i < n; i++) {
- buf[i] = SPI.transfer(0XFF);
- }
- return 0;
- }
-
-
- void send(uint8_t b) {
- SPI.transfer(b);
- }
-
-
- void send(const uint8_t* buf , size_t n) {
- for (size_t i = 0; i < n; i++) {
- SPI.transfer(buf[i]);
- }
- }
-
- bool useSpiTransactions() {
- return true;
- }
- };
- #endif
-
-
- template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin>
- class SdSpiSoft : public SdSpiBase {
- public:
-
-
- void begin() {
- m_spi.begin();
- }
-
-
- void init(uint8_t divisor) {}
-
-
- uint8_t receive() {
- return m_spi.receive();
- }
-
-
- uint8_t receive(uint8_t* buf, size_t n) {
- for (size_t i = 0; i < n; i++) {
- buf[i] = receive();
- }
- return 0;
- }
-
-
- void send(uint8_t data) {
- m_spi.send(data);
- }
-
-
- void send(const uint8_t* buf , size_t n) {
- for (size_t i = 0; i < n; i++) {
- send(buf[i]);
- }
- }
-
- bool useSpiTransactions() {
- return false;
- }
-
- private:
- SoftSPI<MisoPin, MosiPin, SckPin, 0> m_spi;
- };
-
- #if SD_SPI_CONFIGURATION == 0 || SD_SPI_CONFIGURATION >= 3
-
- typedef SdSpi SpiDefault_t;
- #elif SD_SPI_CONFIGURATION == 1
-
- typedef SdSpiLib SpiDefault_t;
- #elif SD_SPI_CONFIGURATION == 2
-
- typedef SdSpiSoft<SOFT_SPI_MISO_PIN, SOFT_SPI_MOSI_PIN, SOFT_SPI_SCK_PIN>
- SpiDefault_t;
- #else
- #error bad SD_SPI_CONFIGURATION
- #endif
-
-
- #ifdef __AVR__
-
- inline void SdSpi::begin() {
- #ifdef __AVR_ATmega328P__
-
- PORTB |= 1 << 2;
- DDRB |= 1 << 2;
- DDRB |= 1 << 3;
- DDRB |= 1 << 5;
- #else
-
-
- digitalWrite(SS, HIGH);
-
-
- pinMode(SS, OUTPUT);
- pinMode(MOSI, OUTPUT);
- pinMode(SCK, OUTPUT);
- #endif
- }
-
- inline void SdSpi::init(uint8_t divisor) {
- uint8_t b = 2;
- uint8_t r = 0;
-
-
- for (; divisor > b && r < 7; b <<= 1, r += r < 5 ? 1 : 2) {}
- SPCR = (1 << SPE) | (1 << MSTR) | (r >> 1);
- SPSR = r & 1 ? 0 : 1 << SPI2X;
- }
-
- inline uint8_t SdSpi::receive() {
- SPDR = 0XFF;
- while (!(SPSR & (1 << SPIF))) {}
- return SPDR;
- }
-
- inline uint8_t SdSpi::receive(uint8_t* buf, size_t n) {
- if (n-- == 0) {
- return 0;
- }
- SPDR = 0XFF;
- for (size_t i = 0; i < n; i++) {
- while (!(SPSR & (1 << SPIF))) {}
- uint8_t b = SPDR;
- SPDR = 0XFF;
- buf[i] = b;
- }
- while (!(SPSR & (1 << SPIF))) {}
- buf[n] = SPDR;
- return 0;
- }
-
- inline void SdSpi::send(uint8_t data) {
- SPDR = data;
- while (!(SPSR & (1 << SPIF))) {}
- }
-
- inline void SdSpi::send(const uint8_t* buf , size_t n) {
- if (n == 0) {
- return;
- }
- SPDR = buf[0];
- if (n > 1) {
- uint8_t b = buf[1];
- size_t i = 2;
- while (1) {
- while (!(SPSR & (1 << SPIF))) {}
- SPDR = b;
- if (i == n) {
- break;
- }
- b = buf[i++];
- }
- }
- while (!(SPSR & (1 << SPIF))) {}
- }
- #endif
- #endif
|