Go Down

Topic: Raw write to SD card (Read 3181 times) previous topic - next topic

Sulya

Hello everyone.

So I had an sd card with quite important data that was not being recognised by all my devices anymore.
I was getting desperate, so I hooked the card to my arduino to see if it was still responding to SPI. To my surprise it was.
It's a 4 gb card mostly filled with photos, so I do not want to copy all the data over serial connection to my PC, as copying data to another SD seems an better option to me- it won't be bottlenecked by serial connection (but even then it will take almost 2 days).

I based my code on https://github.com/tiefpunkt/arduino_sd_recovery/blob/master/sd_recovery_raw.ino
It uses SD.h library and "card.readblock(block,data)" to read the blocks, but using "card.writeblock(block,data)" does not seem to work for me, returns false when I try.

Did anyone else tried to write raw blocks to SD card?

Thanks in advance for any help, here's code:

Code: [Select]
#include <SPI.h>
#include <SD.h>

Sd2Card sd_src; //source card
Sd2Card sd_dst; //destination card

void dst(){ //enable destination card
 digitalWrite(10, HIGH);
 digitalWrite(9, LOW);
}

void src(){ //enable source card
 digitalWrite(10, LOW);//sd_src.chipSelectLow();
 digitalWrite(9, HIGH);//sd_dst.chipSelectHigh();
}

void setup()
{
  Serial.begin(115200);
  pinMode(10, OUTPUT); //sd_src
  pinMode(9, OUTPUT); //sd_dst
 
  Serial.println("Initializing cards...");
  src();
  if(!sd_src.init(SPI_HALF_SPEED, 10)){
   Serial.println("SRC initialisation failed!");
  }
 
  dst();
  if(!sd_dst.init(SPI_HALF_SPEED, 9)){
   Serial.println("DST initialisation failed!"); 
  }
 
  Serial.println("Initialisation done");
//  SD.begin(10);
src();
  long blocks = sd_src.cardSize();

  uint8_t  data[512]; //block buffer
  for (long blockNumber = 0; blockNumber < blocks; blockNumber++) { //for each block of source card
    src();
    if (!sd_src.readBlock(blockNumber, data)) { //try to read block
      Serial.println("Block not read."); //read failed
      break;
    }
   
    dst();
    if (!sd_dst.writeBlock(blockNumber, data)) { //try to write block to destination card
      Serial.println("Block not written. No idea why..."); //write failed
      break;
    }
    Serial.print("Copying block ");
    Serial.print(blockNumber);
    Serial.print(" of ");
    Serial.print(blocks);
    Serial.print(" : ");
    Serial.print(100*blockNumber/blocks, 0);
    Serial.println("% done.");
  }
}

void loop()
{
  // nothing happens after setup finishes.
}

fat16lib

Try editing Sd2Card.h in the SD.h library and change this define at about line 90.
Code: [Select]

/** Protect block zero from write if nonzero */
#define SD_PROTECT_BLOCK_ZERO 1

Sulya

Thanks a lot!
It was indeed the problem, but instead of changing it and letting it to copy the block zero too I've changed start to block one.
I did not find it yet, but it appears that there's something special about block 0, probably some config for the controller and H/W ID's. So I left it in place now and the copying works just fine.

Stopped it after 5 minutes to check the progress, and the filesystem was already copied, as were 1 and a half photo's! I am now sure it will work.

I also minimised the serial output and tested again- now it seems like it will finish in just 21 hours!

Once again, thank you so much!

fat16lib

Quote
It was indeed the problem, but instead of changing it and letting it to copy the block zero too I've changed start to block one.
I did not find it yet, but it appears that there's something special about block 0, probably some config for the controller and H/W ID's. So I left it in place now and the copying works just fine.
There is nothing special about block zero.  I just put that test in the first versions of SdFat to catch bugs.  That was six years ago and the Arduino company never upgraded the SD.h core.

Current versions of SdFat need to write block zero when formatting an SD.

play3r

I am curious, Sulya, how this worked out for you?  Were you able to read or possibly mount the card that was written to?

I know that this is an old thread, but just in case others check here, I took a similar approach ... well two approaches.

- first is a sketch/Python pair of programs (based on DumpFile) which dumps multiple files from the SD via the SPI interface to a directory structure in the directory from which the Python program is run

- second is another sketch/Python pair (somewhat like sd_recovery_raw) which dumps an image of an SD into the directory from which the Python program is run

More details at SD Card Not Recognized

Mike

Go Up