mirror of
https://github.com/arduino/Arduino.git
synced 2025-01-17 06:52:18 +01:00
SD Card ported and tested
This commit is contained in:
parent
1e221116f3
commit
11c0555dcc
@ -90,7 +90,7 @@ struct partitionTable {
|
||||
uint32_t firstSector;
|
||||
/** Length of the partition, in blocks. */
|
||||
uint32_t totalSectors;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
/** Type name for partitionTable */
|
||||
typedef struct partitionTable part_t;
|
||||
//------------------------------------------------------------------------------
|
||||
@ -114,7 +114,7 @@ struct masterBootRecord {
|
||||
uint8_t mbrSig0;
|
||||
/** Second MBR signature byte. Must be 0XAA */
|
||||
uint8_t mbrSig1;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
/** Type name for masterBootRecord */
|
||||
typedef struct masterBootRecord mbr_t;
|
||||
//------------------------------------------------------------------------------
|
||||
@ -236,7 +236,7 @@ struct biosParmBlock {
|
||||
* should always set all of the bytes of this field to 0.
|
||||
*/
|
||||
uint8_t fat32Reserved[12];
|
||||
};
|
||||
} __attribute__((packed));
|
||||
/** Type name for biosParmBlock */
|
||||
typedef struct biosParmBlock bpb_t;
|
||||
//------------------------------------------------------------------------------
|
||||
@ -271,7 +271,7 @@ struct fat32BootSector {
|
||||
uint8_t bootSectorSig0;
|
||||
/** must be 0XAA */
|
||||
uint8_t bootSectorSig1;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
//------------------------------------------------------------------------------
|
||||
// End Of Chain values for FAT entries
|
||||
/** FAT16 end of chain value used by Microsoft. */
|
||||
@ -366,7 +366,7 @@ struct directoryEntry {
|
||||
uint16_t firstClusterLow;
|
||||
/** 32-bit unsigned holding this file's size in bytes. */
|
||||
uint32_t fileSize;
|
||||
};
|
||||
} __attribute__((packed));
|
||||
//------------------------------------------------------------------------------
|
||||
// Definitions for directory entries
|
||||
//
|
||||
|
@ -17,20 +17,32 @@
|
||||
* along with the Arduino Sd2Card Library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#define USE_SPI_LIB
|
||||
#include <Arduino.h>
|
||||
#include "Sd2Card.h"
|
||||
//------------------------------------------------------------------------------
|
||||
#ifndef SOFTWARE_SPI
|
||||
#ifdef USE_SPI_LIB
|
||||
#include <SPI.h>
|
||||
#endif
|
||||
// functions for hardware SPI
|
||||
/** Send a byte to the card */
|
||||
static void spiSend(uint8_t b) {
|
||||
#ifndef USE_SPI_LIB
|
||||
SPDR = b;
|
||||
while (!(SPSR & (1 << SPIF)));
|
||||
#else
|
||||
SPI.transfer(b);
|
||||
#endif
|
||||
}
|
||||
/** Receive a byte from the card */
|
||||
static uint8_t spiRec(void) {
|
||||
#ifndef USE_SPI_LIB
|
||||
spiSend(0XFF);
|
||||
return SPDR;
|
||||
#else
|
||||
return SPI.transfer(0xFF);
|
||||
#endif
|
||||
}
|
||||
#else // SOFTWARE_SPI
|
||||
//------------------------------------------------------------------------------
|
||||
@ -220,11 +232,14 @@ uint8_t Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
|
||||
// set pin modes
|
||||
pinMode(chipSelectPin_, OUTPUT);
|
||||
chipSelectHigh();
|
||||
#ifndef USE_SPI_LIB
|
||||
pinMode(SPI_MISO_PIN, INPUT);
|
||||
pinMode(SPI_MOSI_PIN, OUTPUT);
|
||||
pinMode(SPI_SCK_PIN, OUTPUT);
|
||||
#endif
|
||||
|
||||
#ifndef SOFTWARE_SPI
|
||||
#ifndef USE_SPI_LIB
|
||||
// SS must be in output mode even it is not chip select
|
||||
pinMode(SS_PIN, OUTPUT);
|
||||
digitalWrite(SS_PIN, HIGH); // disable any SPI device using hardware SS pin
|
||||
@ -232,7 +247,15 @@ 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);
|
||||
#endif // SOFTWARE_SPI
|
||||
#else // USE_SPI_LIB
|
||||
SPI.begin();
|
||||
#ifdef SPI_CLOCK_DIV128
|
||||
SPI.setClockDivider(SPI_CLOCK_DIV128);
|
||||
#else
|
||||
SPI.setClockDivider(255);
|
||||
#endif
|
||||
#endif // USE_SPI_LIB
|
||||
#endif // SOFTWARE_SPI
|
||||
|
||||
// must supply min of 74 clock cycles with CS high.
|
||||
for (uint8_t i = 0; i < 10; i++) spiSend(0XFF);
|
||||
@ -456,6 +479,7 @@ uint8_t Sd2Card::setSckRate(uint8_t sckRateID) {
|
||||
error(SD_CARD_ERROR_SCK_RATE);
|
||||
return false;
|
||||
}
|
||||
#ifndef USE_SPI_LIB
|
||||
// see avr processor datasheet for SPI register bit definitions
|
||||
if ((sckRateID & 1) || sckRateID == 6) {
|
||||
SPSR &= ~(1 << SPI2X);
|
||||
@ -465,6 +489,23 @@ uint8_t Sd2Card::setSckRate(uint8_t sckRateID) {
|
||||
SPCR &= ~((1 <<SPR1) | (1 << SPR0));
|
||||
SPCR |= (sckRateID & 4 ? (1 << SPR1) : 0)
|
||||
| (sckRateID & 2 ? (1 << SPR0) : 0);
|
||||
#else // USE_SPI_LIB
|
||||
int v;
|
||||
#ifdef SPI_CLOCK_DIV128
|
||||
switch (sckRateID) {
|
||||
case 0: v=SPI_CLOCK_DIV2; break;
|
||||
case 1: v=SPI_CLOCK_DIV4; break;
|
||||
case 2: v=SPI_CLOCK_DIV8; break;
|
||||
case 3: v=SPI_CLOCK_DIV16; break;
|
||||
case 4: v=SPI_CLOCK_DIV32; break;
|
||||
case 5: v=SPI_CLOCK_DIV64; break;
|
||||
case 6: v=SPI_CLOCK_DIV128; break;
|
||||
}
|
||||
#else // SPI_CLOCK_DIV128
|
||||
v = 2 << sckRateID;
|
||||
#endif // SPI_CLOCK_DIV128
|
||||
SPI.setClockDivider(v);
|
||||
#endif // USE_SPI_LIB
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -31,6 +31,11 @@ uint8_t const SPI_FULL_SPEED = 0;
|
||||
uint8_t const SPI_HALF_SPEED = 1;
|
||||
/** Set SCK rate to F_CPU/8. Sd2Card::setSckRate(). */
|
||||
uint8_t const SPI_QUARTER_SPEED = 2;
|
||||
/**
|
||||
* USE_SPI_LIB: if set, use the SPI library bundled with Arduino IDE, otherwise
|
||||
* run with a standalone driver for AVR.
|
||||
*/
|
||||
#define USE_SPI_LIB
|
||||
/**
|
||||
* Define MEGA_SOFT_SPI non-zero to use software SPI on Mega Arduinos.
|
||||
* Pins used are SS 10, MOSI 11, MISO 12, and SCK 13.
|
||||
@ -66,7 +71,9 @@ uint8_t const SPI_MISO_PIN = MISO_PIN;
|
||||
/** SPI Clock pin */
|
||||
uint8_t const SPI_SCK_PIN = SCK_PIN;
|
||||
/** optimize loops for hardware SPI */
|
||||
#ifndef USE_SPI_LIB
|
||||
#define OPTIMIZE_HARDWARE_SPI
|
||||
#endif
|
||||
|
||||
#else // SOFTWARE_SPI
|
||||
// define software SPI pins so Mega can use unmodified GPS Shield
|
||||
|
@ -17,6 +17,22 @@
|
||||
* along with the Arduino SdFat Library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#if defined(__arm__) // Arduino Due Board follows
|
||||
|
||||
#ifndef Sd2PinMap_h
|
||||
#define Sd2PinMap_h
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
uint8_t const SS_PIN = SS;
|
||||
uint8_t const MOSI_PIN = MOSI;
|
||||
uint8_t const MISO_PIN = MISO;
|
||||
uint8_t const SCK_PIN = SCK;
|
||||
|
||||
#endif // Sd2PinMap_h
|
||||
|
||||
#elif defined(__AVR__) // Other AVR based Boards follows
|
||||
|
||||
// Warning this file was generated by a program.
|
||||
#ifndef Sd2PinMap_h
|
||||
#define Sd2PinMap_h
|
||||
@ -350,3 +366,7 @@ static inline __attribute__((always_inline))
|
||||
}
|
||||
}
|
||||
#endif // Sd2PinMap_h
|
||||
|
||||
#else
|
||||
#error Architecture or board not supported.
|
||||
#endif
|
||||
|
@ -23,7 +23,9 @@
|
||||
* \file
|
||||
* SdFile and SdVolume classes
|
||||
*/
|
||||
#ifdef __AVR__
|
||||
#include <avr/pgmspace.h>
|
||||
#endif
|
||||
#include "Sd2Card.h"
|
||||
#include "FatStructs.h"
|
||||
#include "Print.h"
|
||||
@ -286,8 +288,10 @@ class SdFile : public Print {
|
||||
size_t write(uint8_t b);
|
||||
size_t write(const void* buf, uint16_t nbyte);
|
||||
size_t write(const char* str);
|
||||
#ifdef __AVR__
|
||||
void write_P(PGM_P str);
|
||||
void writeln_P(PGM_P str);
|
||||
#endif
|
||||
//------------------------------------------------------------------------------
|
||||
#if ALLOW_DEPRECATED_FUNCTIONS
|
||||
// Deprecated functions - suppress cpplint warnings with NOLINT comment
|
||||
|
@ -24,12 +24,14 @@
|
||||
* Useful utility functions.
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
#ifdef __AVR__
|
||||
#include <avr/pgmspace.h>
|
||||
/** Store and print a string in flash memory.*/
|
||||
#define PgmPrint(x) SerialPrint_P(PSTR(x))
|
||||
/** Store and print a string in flash memory followed by a CR/LF.*/
|
||||
#define PgmPrintln(x) SerialPrintln_P(PSTR(x))
|
||||
/** Defined so doxygen works for function definitions. */
|
||||
#endif
|
||||
#define NOINLINE __attribute__((noinline,unused))
|
||||
#define UNUSEDOK __attribute__((unused))
|
||||
//------------------------------------------------------------------------------
|
||||
@ -49,6 +51,7 @@ static UNUSEDOK int FreeRam(void) {
|
||||
}
|
||||
return free_memory;
|
||||
}
|
||||
#ifdef __AVR__
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* %Print a string in flash memory to the serial port.
|
||||
@ -68,4 +71,5 @@ static NOINLINE void SerialPrintln_P(PGM_P str) {
|
||||
SerialPrint_P(str);
|
||||
Serial.println();
|
||||
}
|
||||
#endif // __AVR__
|
||||
#endif // #define SdFatUtil_h
|
||||
|
@ -18,7 +18,9 @@
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <SdFat.h>
|
||||
#ifdef __AVR__
|
||||
#include <avr/pgmspace.h>
|
||||
#endif
|
||||
#include <Arduino.h>
|
||||
//------------------------------------------------------------------------------
|
||||
// callback function for date/time
|
||||
@ -256,9 +258,15 @@ uint8_t SdFile::make83Name(const char* str, uint8_t* name) {
|
||||
i = 8; // place for extension
|
||||
} else {
|
||||
// illegal FAT characters
|
||||
PGM_P p = PSTR("|<>^+=?/[];,*\"\\");
|
||||
uint8_t b;
|
||||
#if defined(__AVR__)
|
||||
PGM_P p = PSTR("|<>^+=?/[];,*\"\\");
|
||||
while ((b = pgm_read_byte(p++))) if (b == c) return false;
|
||||
#elif defined(__arm__)
|
||||
const uint8_t valid[] = "|<>^+=?/[];,*\"\\";
|
||||
const uint8_t *p = valid;
|
||||
while ((b = *p++)) if (b == c) return false;
|
||||
#endif
|
||||
// check size and only allow ASCII printable characters
|
||||
if (i > n || c < 0X21 || c > 0X7E)return false;
|
||||
// only upper case allowed in 8.3 names - convert lower to upper
|
||||
@ -1232,6 +1240,7 @@ size_t SdFile::write(uint8_t b) {
|
||||
size_t SdFile::write(const char* str) {
|
||||
return write(str, strlen(str));
|
||||
}
|
||||
#ifdef __AVR__
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* Write a PROGMEM string to a file.
|
||||
@ -1251,3 +1260,4 @@ void SdFile::writeln_P(PGM_P str) {
|
||||
write_P(str);
|
||||
println();
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user