Browse Source

Add SPI transaction support

main
PaulStoffregen 10 years ago
parent
commit
1416d3aebd
7 changed files with 47 additions and 47 deletions
  1. +1
    -0
      examples/CardInfo/CardInfo.ino
  2. +1
    -0
      examples/Datalogger/Datalogger.ino
  3. +1
    -0
      examples/DumpFile/DumpFile.ino
  4. +1
    -0
      examples/Files/Files.ino
  5. +1
    -0
      examples/ReadWrite/ReadWrite.ino
  6. +1
    -0
      examples/listfiles/listfiles.ino
  7. +41
    -47
      utility/Sd2Card.cpp

+ 1
- 0
examples/CardInfo/CardInfo.ino View File

@@ -21,6 +21,7 @@
*/
// include the SD library:
#include <SD.h>
#include <SPI.h>

// set up variables using the SD utility library functions:
Sd2Card card;

+ 1
- 0
examples/Datalogger/Datalogger.ino View File

@@ -21,6 +21,7 @@
*/

#include <SD.h>
#include <SPI.h>

// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,

+ 1
- 0
examples/DumpFile/DumpFile.ino View File

@@ -21,6 +21,7 @@
*/

#include <SD.h>
#include <SPI.h>

// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,

+ 1
- 0
examples/Files/Files.ino View File

@@ -18,6 +18,7 @@
*/
#include <SD.h>
#include <SPI.h>

File myFile;


+ 1
- 0
examples/ReadWrite/ReadWrite.ino View File

@@ -19,6 +19,7 @@
*/
#include <SD.h>
#include <SPI.h>

File myFile;


+ 1
- 0
examples/listfiles/listfiles.ino View File

@@ -18,6 +18,7 @@
*/
#include <SD.h>
#include <SPI.h>

File root;


+ 41
- 47
utility/Sd2Card.cpp View File

@@ -21,12 +21,15 @@
#include <SPI.h>
#include "Sd2Card.h"
#ifdef SPI_HAS_TRANSACTION
static SPISettings settings;
#endif
#if defined(__MK20DX128__) || defined(__MK20DX256__)
#define USE_TEENSY3_SPI
// Teensy 3.0 functions (copied from sdfatlib20130629)
#include <mk20dx128.h>
// Limit initial fifo to three entries to avoid fifo overrun
@@ -47,48 +50,16 @@ static void spiBegin() {
}
static void spiInit(uint8_t spiRate) {
// spiRate = 0 : 24 or 12 Mbit/sec
// spiRate = 1 : 12 or 6 Mbit/sec
// spiRate = 2 : 6 or 3 Mbit/sec
// spiRate = 3 : 4 or 2.0 Mbit/sec
// spiRate = 4 : 3 or 1.5 Mbit/sec
// spiRate = 5 : 250 kbit/sec
// spiRate = 6 : 125 kbit/sec
uint32_t ctar, ctar0, ctar1;
switch (spiRate/2) {
// 1/2 speed
case 0: ctar = SPI_CTAR_DBR | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0); break;
// 1/4 speed
case 1: ctar = SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0); break;
// 1/8 speed
case 2: ctar = SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1); break;
// 1/12 speed
case 3: ctar = SPI_CTAR_BR(2) | SPI_CTAR_CSSCK(2); break;
// 1/16 speed
case 4: ctar = SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(3); break;
#if F_BUS == 48000000
case 5: ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(5); break;
default: ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(6);
#elif F_BUS == 24000000
case 5: ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(4); break;
default: ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(5);
#else
#error "MK20DX128 bus frequency must be 48 or 24 MHz"
#endif
}
// CTAR0 - 8 bit transfer
ctar0 = ctar | SPI_CTAR_FMSZ(7);
// CTAR1 - 16 bit transfer
ctar1 = ctar | SPI_CTAR_FMSZ(15);
if (SPI0_CTAR0 != ctar0 || SPI0_CTAR1 != ctar1) {
SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
SPI0_CTAR0 = ctar0;
SPI0_CTAR1 = ctar1;
}
SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F);
SPCR.enable_pins();
switch (spiRate) {
case 0: settings = SPISettings(12000000, MSBFIRST, SPI_MODE0); break;
case 1: settings = SPISettings(8000000, MSBFIRST, SPI_MODE0); break;
case 2: settings = SPISettings(6000000, MSBFIRST, SPI_MODE0); break;
case 3: settings = SPISettings(4000000, MSBFIRST, SPI_MODE0); break;
case 4: settings = SPISettings(3000000, MSBFIRST, SPI_MODE0); break;
case 5: settings = SPISettings(2000000, MSBFIRST, SPI_MODE0); break;
default: settings = SPISettings(400000, MSBFIRST, SPI_MODE0);
}
SPI.begin();
}
/** SPI receive a byte */
@@ -289,9 +260,15 @@ uint32_t Sd2Card::cardSize(void) {
//------------------------------------------------------------------------------
void Sd2Card::chipSelectHigh(void) {
digitalWrite(chipSelectPin_, HIGH);
#ifdef SPI_HAS_TRANSACTION
SPI.endTransaction();
#endif
}
//------------------------------------------------------------------------------
void Sd2Card::chipSelectLow(void) {
#ifdef SPI_HAS_TRANSACTION
SPI.beginTransaction(settings);
#endif
digitalWrite(chipSelectPin_, LOW);
}
//------------------------------------------------------------------------------
@@ -382,10 +359,19 @@ uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0);
// clear double speed
SPSR &= ~(1 << SPI2X);
#ifdef SPI_HAS_TRANSACTION
settings = SPISettings(250000, MSBFIRST, SPI_MODE0);
#endif
#endif // not USE_TEENSY3_SPI
// must supply min of 74 clock cycles with CS high.
#ifdef SPI_HAS_TRANSACTION
SPI.beginTransaction(settings);
#endif
for (uint8_t i = 0; i < 10; i++) spiSend(0XFF);
#ifdef SPI_HAS_TRANSACTION
SPI.endTransaction();
#endif
chipSelectLow();
@@ -624,10 +610,7 @@ uint8_t Sd2Card::setSckRate(uint8_t sckRateID) {
spiInit(sckRateID);
return true;
#else
if (sckRateID > 6) {
error(SD_CARD_ERROR_SCK_RATE);
return false;
}
if (sckRateID > 6) sckRateID = 6;
// see avr processor datasheet for SPI register bit definitions
if ((sckRateID & 1) || sckRateID == 6) {
SPSR &= ~(1 << SPI2X);
@@ -637,6 +620,17 @@ uint8_t Sd2Card::setSckRate(uint8_t sckRateID) {
SPCR &= ~((1 <<SPR1) | (1 << SPR0));
SPCR |= (sckRateID & 4 ? (1 << SPR1) : 0)
| (sckRateID & 2 ? (1 << SPR0) : 0);
#ifdef SPI_HAS_TRANSACTION
switch (sckRateID) {
case 0: settings = SPISettings(8000000, MSBFIRST, SPI_MODE0); break;
case 1: settings = SPISettings(4000000, MSBFIRST, SPI_MODE0); break;
case 2: settings = SPISettings(2000000, MSBFIRST, SPI_MODE0); break;
case 3: settings = SPISettings(1000000, MSBFIRST, SPI_MODE0); break;
case 4: settings = SPISettings(500000, MSBFIRST, SPI_MODE0); break;
case 5: settings = SPISettings(250000, MSBFIRST, SPI_MODE0); break;
default: settings = SPISettings(125000, MSBFIRST, SPI_MODE0);
}
#endif
return true;
#endif
}

Loading…
Cancel
Save