/*
* Copyright (c) 2006-2007 by Roland Riegel <feedback@roland-riegel.de>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
//striped down for small block access for use as large eeprom
//26.8.2011 Deif Keller
#ifndef SD_RAW_H
#define SD_RAW_H
#include "WProgram.h"
#include <stdint.h>
//#include "sd_raw_config.h"
//use software spi
#define SD_RAW_SOFTSPI
//use atmega 328... did not work automatically for me
//#define __AVR_ATmega328p__
//define the block size to read and write
#define BLOCK_SIZE 32
/* defines for customisation of sd/mmc port access */
#if defined SD_RAW_SOFTSPI
// arduino pins for soft spi
#define pinClk 13
#define pinDataOut 11
#define pinDataIn 12
#define pinSdCs 10
#define select_card() digitalWrite(pinSdCs,LOW)
#define unselect_card() digitalWrite(pinSdCs,HIGH)
#elif defined(__AVR_ATmega8__) || \
defined(__AVR_ATmega48__) || \
defined(__AVR_ATmega88__) || \
defined(__AVR_ATmega328p__) || \
defined(__AVR_ATmega168__)
#define configure_pin_mosi() DDRB |= (1 << DDB3)
#define configure_pin_sck() DDRB |= (1 << DDB5)
#define configure_pin_ss() DDRB |= (1 << DDB2)
#define configure_pin_miso() DDRB &= ~(1 << DDB4)
#define select_card() PORTB &= ~(1 << PB2)
#define unselect_card() PORTB |= (1 << PB2)
#elif defined(__AVR_ATmega16__) || \
defined(__AVR_ATmega32__)
#define configure_pin_mosi() DDRB |= (1 << DDB5)
#define configure_pin_sck() DDRB |= (1 << DDB7)
#define configure_pin_ss() DDRB |= (1 << DDB4)
#define configure_pin_miso() DDRB &= ~(1 << DDB6)
#define select_card() PORTB &= ~(1 << PB4)
#define unselect_card() PORTB |= (1 << PB4)
#elif defined(__AVR_ATmega64__) || \
defined(__AVR_ATmega128__) || \
defined(__AVR_ATmega169__)
#define configure_pin_mosi() DDRB |= (1 << DDB2)
#define configure_pin_sck() DDRB |= (1 << DDB1)
#define configure_pin_ss() DDRB |= (1 << DDB0)
#define configure_pin_miso() DDRB &= ~(1 << DDB3)
#define select_card() PORTB &= ~(1 << PB0)
#define unselect_card() PORTB |= (1 << PB0)
#else
#error "no sd/mmc pin mapping available!"
#endif
/**
* This struct is used by sd_raw_get_info() to return
* manufacturing and status information of the card.
*/
struct sd_raw_info
{
/**
* A manufacturer code globally assigned by the SD card organization.
*/
uint8_t manufacturer;
/**
* A string describing the card's OEM or content, globally assigned by the SD card organization.
*/
uint8_t oem[3];
/**
* A product name.
*/
uint8_t product[6];
/**
* The card's revision, coded in packed BCD.
*
* For example, the revision value \c 0x32 means "3.2".
*/
uint8_t revision;
/**
* A serial number assigned by the manufacturer.
*/
uint32_t serial;
/**
* The year of manufacturing.
*
* A value of zero means year 2000.
*/
uint8_t manufacturing_year;
/**
* The month of manufacturing.
*/
uint8_t manufacturing_month;
/**
* The card's total capacity in bytes.
*/
uint32_t capacity;
/**
* Defines wether the card's content is original or copied.
*
* A value of \c 0 means original, \c 1 means copied.
*/
uint8_t flag_copy;
/**
* Defines wether the card's content is write-protected.
*
* \note This is an internal flag and does not represent the
* state of the card's mechanical write-protect switch.
*/
uint8_t flag_write_protect;
/**
* Defines wether the card's content is temporarily write-protected.
*
* \note This is an internal flag and does not represent the
* state of the card's mechanical write-protect switch.
*/
uint8_t flag_write_protect_temp;
/**
* The card's data layout.
*
* See the \c SD_RAW_FORMAT_* constants for details.
*
* \note This value is not guaranteed to match reality.
*/
uint8_t format;
};
uint8_t sd_raw_init();
uint8_t sd_raw_get_info(struct sd_raw_info* info);
uint8_t sd_raw_read_block(uint32_t block, uint8_t* buffer);
uint8_t sd_raw_write_block(uint32_t block, const uint8_t* buffer);
/**
* @}
*/
#endif
sd_raw_test.pde
//#include "sd-reader_config.h"
#include "sd_raw.h"
int print_disk_info();
int sample();
int readDisk();
byte incomingByte;
void printWelcome();
long int address;
byte tempBytes[2];
void setup()
{
Serial.begin(9600);
delay(1000);
if(!sd_raw_init())
{
Serial.println("MMC/SD initialization failed");
while (true);
}
print_disk_info();
Serial.println("");
Serial.println("");
#define len 32
unsigned char data[len];
int i;
for (i=0; i< len; i++){
data[i] = i + 20;
}
Serial.println("--------- write -----------");
sd_raw_write_block(0,data);
for (i=0; i< len; i++){
data[i] = i + 100;
}
Serial.println("--------- write -----------");
sd_raw_write_block(512,data);
for (i=0; i< len; i++){
data[i] = 0;
}
Serial.println("--------- read -----------");
sd_raw_read_block(0,data);
for (i=0; i< len; i++){
Serial.println(data[i],DEC);
}
Serial.println("--------- read -----------");
sd_raw_read_block(1,data);
for (i=0; i< len; i++){
Serial.println(data[i],DEC);
}
while (true);
}
void loop()
{
}
int print_disk_info()
{
struct sd_raw_info disk_info;
if(!sd_raw_get_info(&disk_info))
{
return 0;
}
Serial.println();
Serial.print("rev: ");
Serial.print(disk_info.revision,HEX);
Serial.println();
Serial.print("serial: 0x");
Serial.print(disk_info.serial,HEX);
Serial.println();
Serial.print("date: ");
Serial.print(disk_info.manufacturing_month,DEC);
Serial.println();
Serial.print(disk_info.manufacturing_year,DEC);
Serial.println();
Serial.print("size: ");
Serial.print(disk_info.capacity,DEC);
Serial.println();
Serial.print("copy: ");
Serial.print(disk_info.flag_copy,DEC);
Serial.println();
Serial.print("wr.pr.: ");
Serial.print(disk_info.flag_write_protect_temp,DEC);
Serial.print('/');
Serial.print(disk_info.flag_write_protect,DEC);
Serial.println();
Serial.print("format: ");
Serial.print(disk_info.format,DEC);
Serial.println();
Serial.print("free: ");
return 1;
}
I am tired of optimizing my long sketch for more free RAM... the problem was with SD library and after some experiments with a test function the result was that SD library eat ~500 bytes RAM. (Madness)
Steps you have done sounds promising! I need SD for logging data (slow speed) and manual upload the file via serial to PC (weekly). Can you explain what should I do to start using your library? Where to copy files?
sorry for my slow reply rate....
I dont check this site verry often.
actually it does not.
I noticed that most sd cards do not support smaler block sizes than 512bytes.
I changed the code so it always uses 512 byte blocks but does not fill them up.
if you use smaler blocks it just wastes the remaining sd space but since those cards are verry large I dont care.
all you need to use the code are the functions
uint8_t sd_raw_init()
uint8_t sd_raw_read_block(uint32_t block, uint8_t* buffer, int len)
uint8_t sd_raw_write_block(uint32_t block, const uint8_t* buffer, int len)
block is the block address (not the byte address: 1 means the block starting at byte 512)
buffer the databuffer to write / read and len the length of the buffer.
the functions
uint8_t sd_raw_get_info(struct sd_raw_info* info) (commented out for lower memory consumption)
void decodeResponse1(char response)
are practical for debuging purposes