...
 
Commits (2)
/*
SD card test
This example shows how use the utility libraries on which the'
SD library is based in order to get info about your SD card.
Very useful for testing a card when you're not sure whether its working or not.
The circuit:
SD card attached to SPI bus as follows:
** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
** CS - depends on your SD card shield or module.
Pin 4 used here for consistency with other Arduino examples
created 28 Mar 2011
by Limor Fried
modified 9 Apr 2012
by Tom Igoe
*/
// include the SD library:
#include <SPI.h>
#include <SD.h>
// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;
// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// MKRZero SD: SDCARD_SS_PIN
const int chipSelect = 4;
void setup() {
// Open serial communications and wait for port to open:
/*
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
*/
//Serial.print("\nInitializing SD card...");
// we'll use the initialization code from the utility libraries
// since we're just testing if the card is working!
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
//Serial.println("initialization failed. Things to check:");
//Serial.println("* is a card inserted?");
//Serial.println("* is your wiring correct?");
//Serial.println("* did you change the chipSelect pin to match your shield or module?");
while (1);
} else {
//Serial.println("Wiring is correct and a card is present.");
}
// print the type of card
//Serial.println();
//Serial.print("Card type: ");
/*
switch (card.type()) {
case SD_CARD_TYPE_SD1:
//Serial.println("SD1");
break;
case SD_CARD_TYPE_SD2:
//Serial.println("SD2");
break;
case SD_CARD_TYPE_SDHC:
//Serial.println("SDHC");
break;
default:
//Serial.println("Unknown");
}
*/
// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
if (!volume.init(card)) {
//Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
while (1);
}
//Serial.print("Clusters: ");
//Serial.println(volume.clusterCount());
//Serial.print("Blocks x Cluster: ");
//Serial.println(volume.blocksPerCluster());
//Serial.print("Total Blocks: ");
//Serial.println(volume.blocksPerCluster() * volume.clusterCount());
//Serial.println();
// print the type and size of the first FAT-type volume
uint32_t volumesize;
//Serial.print("Volume type is: FAT");
//Serial.println(volume.fatType(), DEC);
volumesize = volume.blocksPerCluster(); // clusters are collections of blocks
volumesize *= volume.clusterCount(); // we'll have a lot of clusters
volumesize /= 2; // SD card blocks are always 512 bytes (2 blocks are 1KB)
//Serial.print("Volume size (Kb): ");
//Serial.println(volumesize);
//Serial.print("Volume size (Mb): ");
volumesize /= 1024;
//Serial.println(volumesize);
//Serial.print("Volume size (Gb): ");
//Serial.println((float)volumesize / 1024.0);
//Serial.println("\nFiles found on the card (name, date and size in bytes): ");
root.openRoot(volume);
// list all files in the card with date and size
root.ls(LS_R | LS_DATE | LS_SIZE);
}
void loop(void) {
}
...@@ -221,7 +221,7 @@ unsigned char SPI_write(uint8_t chr) { ...@@ -221,7 +221,7 @@ unsigned char SPI_write(uint8_t chr) {
// SD_command // SD_command
// write an SD command and return the response // write an SD command and return the response
// //
void SD_command(uint8_t command,uint32_t argument,uint8_t CRC,uint8_t *result) { void SD_command(uint8_t command, uint32_t argument, uint8_t CRC, uint8_t *result) {
clear(CS_port,CS_pin); clear(CS_port,CS_pin);
SPI_write(command); SPI_write(command);
SPI_write((argument >> 24) & 0xFF); SPI_write((argument >> 24) & 0xFF);
...@@ -300,49 +300,22 @@ void SD_read(uint32_t sector,uint16_t offset,uint8_t *buffer,uint16_t size) { ...@@ -300,49 +300,22 @@ void SD_read(uint32_t sector,uint16_t offset,uint8_t *buffer,uint16_t size) {
set(CS_port,CS_pin); set(CS_port,CS_pin);
} }
// void sd_loop() {
// main static uint8_t count, sectors_per_cluster, FATs, attribute, result[8], buffer[50];
// static uint16_t bytes_per_sector, reserved_sectors, offset, file_cluster_low, file_cluster_hi,
int main(void) { buffer_length, sector_count;
// static uint32_t partition, FAT_sectors, fat_sector, root_cluster, root_sector, file_length,
// main file_cluster, file_sector, chars_read;
//
// Debug loop to verify we can detect when the card is inserted // Wait for card to be inserted
// Configure DETECT_pin as an input and led_pin as an output while (PINA & DETECT_pin) {
DETECT_direction &= ~DETECT_pin; led_port |= led_pin;
led_direction |= led_pin; _delay_ms(200);
while (1) { led_port &= ~led_pin;
if (PINA & DETECT_pin) { _delay_ms(200);
led_port &= ~led_pin;
} else {
led_port |= led_pin;
}
} }
led_port |= led_pin;
static uint8_t count,sectors_per_cluster,FATs,attribute,result[8],buffer[50];
static uint16_t bytes_per_sector,reserved_sectors,offset,
file_cluster_low,file_cluster_hi,buffer_length,sector_count;
static uint32_t partition,FAT_sectors,fat_sector,root_cluster,
root_sector,file_length,file_cluster,file_sector,chars_read;
//
// set clock divider to /1
//
CLKPR = (1 << CLKPCE);
CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
//
// initialize output pins
//
set(serial_port,serial_pin_out);
output(serial_direction,serial_pin_out);
set(CS_port,CS_pin);
output(CS_direction,CS_pin);
clear(MOSI_port,MOSI_pin);
output(MOSI_direction,MOSI_pin);
set(SCK_port,SCK_pin);
output(SCK_direction,SCK_pin);
set(MISO_port,MISO_pin); //turn on pull-up
input(MISO_direction,MISO_pin);
// //
// put card in SPI mode // put card in SPI mode
// //
...@@ -354,20 +327,23 @@ int main(void) { ...@@ -354,20 +327,23 @@ int main(void) {
clear(SCK_port,SCK_pin); clear(SCK_port,SCK_pin);
SPI_delay(); SPI_delay();
} }
// //
// CMD0: reset and enter idle state // CMD0: reset and enter idle state
// should return 0x01 // should return 0x01
// //
put_flash_string(PSTR("\r\nreset: 0x")); put_flash_string(PSTR("\r\nreset: 0x"));
SD_command(0x40,0,0x95,result); SD_command(0x40, 0, 0x95, result);
put_hex_string(result,8); put_hex_string(result,8);
// //
// CMD8: send interface condition, set SDHC // CMD8: send interface condition, set SDHC
// should return 0x01000001AA // should return 0x01000001AA
// //
put_flash_string(PSTR("\r\nset interface: 0x")); put_flash_string(PSTR("\r\nset interface: 0x"));
SD_command(0x48,0x000001AA,0x87,result); SD_command(0x48, 0x000001AA, 0x87, result);
put_hex_string(result,8); put_hex_string(result,8);
// //
// initialization loop // initialization loop
// //
...@@ -378,21 +354,31 @@ int main(void) { ...@@ -378,21 +354,31 @@ int main(void) {
// should return 0x01 // should return 0x01
// //
put_flash_string(PSTR("\r\n application command: ")); put_flash_string(PSTR("\r\n application command: "));
SD_command(0x77,0,0,result); SD_command(0x77, 0, 0, result);
put_hex_string(result,8); put_hex_string(result, 8);
// //
// ACMD41: initialize the card // ACMD41: initialize the card
// should return 0x00 when ready // should return 0x00 when ready
// //
put_flash_string(PSTR("\r\n initialize card: 0x")); put_flash_string(PSTR("\r\n initialize card: 0x"));
SD_command(0x69,0x40000000,0,result); SD_command(0x69, 0x40000000, 0, result);
put_hex_string(result,8); put_hex_string(result,8);
// //
// check if done // check if done
// //
if (result[1] == 0) if (result[1] == 0) {
put_string("\ncard initialized");
break; break;
} }
if (PINA & DETECT_pin) {
put_string("\ncard removed");
return;
}
}
// //
// read the first partition table // read the first partition table
// //
...@@ -403,6 +389,7 @@ int main(void) { ...@@ -403,6 +389,7 @@ int main(void) {
put_flash_string(PSTR("\r\n first sector: 0x")); put_flash_string(PSTR("\r\n first sector: 0x"));
put_hex_string(buffer+8,4); put_hex_string(buffer+8,4);
memcpy(&partition,buffer+8,4); memcpy(&partition,buffer+8,4);
// //
// read the first partition block // read the first partition block
// //
...@@ -442,6 +429,7 @@ int main(void) { ...@@ -442,6 +429,7 @@ int main(void) {
put_hex_char((root_cluster >> 16) & 0xFF); put_hex_char((root_cluster >> 16) & 0xFF);
put_hex_char((root_cluster >> 8) & 0xFF); put_hex_char((root_cluster >> 8) & 0xFF);
put_hex_char(root_cluster & 0xFF); put_hex_char(root_cluster & 0xFF);
// //
// read the root directory // read the root directory
// //
...@@ -498,6 +486,7 @@ int main(void) { ...@@ -498,6 +486,7 @@ int main(void) {
} }
offset += 32; offset += 32;
} }
// //
// read the file // read the file
// //
...@@ -520,6 +509,7 @@ int main(void) { ...@@ -520,6 +509,7 @@ int main(void) {
put_char_string(buffer,buffer_length); put_char_string(buffer,buffer_length);
chars_read += buffer_length; chars_read += buffer_length;
offset += buffer_length; offset += buffer_length;
// //
// check sector length // check sector length
// //
...@@ -549,9 +539,48 @@ int main(void) { ...@@ -549,9 +539,48 @@ int main(void) {
offset = 0; offset = 0;
} }
} }
// //
// sector length not reached, continue // sector length not reached, continue
// //
} }
put_flash_string(PSTR("\r\n\r\nend of file\r\n")); put_flash_string(PSTR("\r\n\r\nend of file\r\n"));
led_port &= ~led_pin;
}
//
// main
//
int main(void) {
//
// main
//
//
// set clock divider to /1
//
CLKPR = (1 << CLKPCE);
CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
// Configure DETECT_pin as an input and led_pin as an output
DETECT_direction &= ~DETECT_pin;
led_direction |= led_pin;
//
// initialize output pins
//
set(serial_port,serial_pin_out);
output(serial_direction,serial_pin_out);
set(CS_port,CS_pin);
output(CS_direction,CS_pin);
clear(MOSI_port,MOSI_pin);
output(MOSI_direction,MOSI_pin);
set(SCK_port,SCK_pin);
output(SCK_direction,SCK_pin);
set(MISO_port,MISO_pin); //turn on pull-up
input(MISO_direction,MISO_pin);
while (1) {
sd_loop();
}
} }