|
|
|
|
|
|
|
|
* <http://www.gnu.org/licenses/>.
|
|
|
* <http://www.gnu.org/licenses/>.
|
|
|
*/
|
|
|
*/
|
|
|
#include <Arduino.h>
|
|
|
#include <Arduino.h>
|
|
|
|
|
|
#include <SPI.h>
|
|
|
#include "Sd2Card.h"
|
|
|
#include "Sd2Card.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(__MK20DX128__) || defined(__MK20DX256__)
|
|
|
#if defined(__MK20DX128__) || defined(__MK20DX256__)
|
|
|
#define USE_TEENSY3_SPI
|
|
|
#define USE_TEENSY3_SPI
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
//------------------------------------------------------------------------------
|
|
|
#elif !defined(SOFTWARE_SPI)
|
|
|
|
|
|
|
|
|
#else
|
|
|
// functions for hardware SPI
|
|
|
// functions for hardware SPI
|
|
|
/** Send a byte to the card */
|
|
|
/** Send a byte to the card */
|
|
|
static void spiSend(uint8_t b) {
|
|
|
static void spiSend(uint8_t b) {
|
|
|
|
|
|
|
|
|
return SPDR;
|
|
|
return SPDR;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#else // SOFTWARE_SPI
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
/** nop to tune soft SPI timing */
|
|
|
|
|
|
#define nop asm volatile ("nop\n\t")
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
/** Soft SPI receive */
|
|
|
|
|
|
uint8_t spiRec(void) {
|
|
|
|
|
|
uint8_t data = 0;
|
|
|
|
|
|
// no interrupts during byte receive - about 8 us
|
|
|
|
|
|
cli();
|
|
|
|
|
|
// output pin high - like sending 0XFF
|
|
|
|
|
|
fastDigitalWrite(SPI_MOSI_PIN, HIGH);
|
|
|
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
|
|
|
|
fastDigitalWrite(SPI_SCK_PIN, HIGH);
|
|
|
|
|
|
|
|
|
|
|
|
// adjust so SCK is nice
|
|
|
|
|
|
nop;
|
|
|
|
|
|
nop;
|
|
|
|
|
|
|
|
|
|
|
|
data <<= 1;
|
|
|
|
|
|
|
|
|
|
|
|
if (fastDigitalRead(SPI_MISO_PIN)) data |= 1;
|
|
|
|
|
|
|
|
|
|
|
|
fastDigitalWrite(SPI_SCK_PIN, LOW);
|
|
|
|
|
|
}
|
|
|
|
|
|
// enable interrupts
|
|
|
|
|
|
sei();
|
|
|
|
|
|
return data;
|
|
|
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
/** Soft SPI send */
|
|
|
|
|
|
void spiSend(uint8_t data) {
|
|
|
|
|
|
// no interrupts during byte send - about 8 us
|
|
|
|
|
|
cli();
|
|
|
|
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
|
|
|
|
fastDigitalWrite(SPI_SCK_PIN, LOW);
|
|
|
|
|
|
|
|
|
|
|
|
fastDigitalWrite(SPI_MOSI_PIN, data & 0X80);
|
|
|
|
|
|
|
|
|
|
|
|
data <<= 1;
|
|
|
|
|
|
|
|
|
|
|
|
fastDigitalWrite(SPI_SCK_PIN, HIGH);
|
|
|
|
|
|
}
|
|
|
|
|
|
// hold SCK high for a few ns
|
|
|
|
|
|
nop;
|
|
|
|
|
|
nop;
|
|
|
|
|
|
nop;
|
|
|
|
|
|
nop;
|
|
|
|
|
|
|
|
|
|
|
|
fastDigitalWrite(SPI_SCK_PIN, LOW);
|
|
|
|
|
|
// enable interrupts
|
|
|
|
|
|
sei();
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif // SOFTWARE_SPI
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pinMode(SPI_MISO_PIN, INPUT);
|
|
|
pinMode(SPI_MISO_PIN, INPUT);
|
|
|
pinMode(SPI_MOSI_PIN, OUTPUT);
|
|
|
pinMode(SPI_MOSI_PIN, OUTPUT);
|
|
|
pinMode(SPI_SCK_PIN, OUTPUT);
|
|
|
pinMode(SPI_SCK_PIN, OUTPUT);
|
|
|
#ifndef SOFTWARE_SPI
|
|
|
|
|
|
// SS must be in output mode even it is not chip select
|
|
|
// SS must be in output mode even it is not chip select
|
|
|
pinMode(SS_PIN, OUTPUT);
|
|
|
pinMode(SS_PIN, OUTPUT);
|
|
|
digitalWrite(SS_PIN, HIGH); // disable any SPI device using hardware SS pin
|
|
|
digitalWrite(SS_PIN, HIGH); // disable any SPI device using hardware SS pin
|
|
|
|
|
|
|
|
|
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0);
|
|
|
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0);
|
|
|
// clear double speed
|
|
|
// clear double speed
|
|
|
SPSR &= ~(1 << SPI2X);
|
|
|
SPSR &= ~(1 << SPI2X);
|
|
|
#endif // SOFTWARE_SPI
|
|
|
|
|
|
#endif // not USE_TEENSY3_SPI
|
|
|
#endif // not USE_TEENSY3_SPI
|
|
|
|
|
|
|
|
|
// must supply min of 74 clock cycles with CS high.
|
|
|
// must supply min of 74 clock cycles with CS high.
|
|
|
|
|
|
|
|
|
}
|
|
|
}
|
|
|
chipSelectHigh();
|
|
|
chipSelectHigh();
|
|
|
|
|
|
|
|
|
#ifndef SOFTWARE_SPI
|
|
|
|
|
|
return setSckRate(sckRateID);
|
|
|
return setSckRate(sckRateID);
|
|
|
#else // SOFTWARE_SPI
|
|
|
|
|
|
return true;
|
|
|
|
|
|
#endif // SOFTWARE_SPI
|
|
|
|
|
|
|
|
|
|
|
|
fail:
|
|
|
fail:
|
|
|
chipSelectHigh();
|
|
|
chipSelectHigh();
|