Go Down

Topic: My class wont work in the Arduino library. (Read 1 time) previous topic - next topic

carl47

I wrote a class to read and write blocks of data to a sd card.

If I have the .cpp and .h in the program folder it all works.

#include "SDCARD.h";
SDCARD sd;  //create instance
sd.writeblock(1000);  //write the block to card

I now put the .cpp and .h into a folder in the hardware/libraries
sub-directory of the Arduino application directory.

when I run arduino it generates the object file SDCARD.o in the folder.

#include <SDCARD.h>
SDCARD sd;  //create instance
Up to this stage it compiles ok when I add

sd.writeblock(1000);  //write the block to card

The compiler says compiling but gives an error message

couldn't determine program size:

I tried as much as I can think of..........any hints ?

Coding Badly


carl47

This is my PDE file :

Code: [Select]

#include "SDCARD.h";
volatile unsigned char buffer[512] ;
int inByte =0;
unsigned long time;

void setup()                    // run once, when the sketch starts
{
Serial.begin(9600);                     // initialize serial communication with computer  
}

void loop()                     // run over and over again
{
SDCARD sd;
unsigned char response;
  if (Serial.available() > 0)   // read the oldest byte in the serial buffer:
  {
   inByte = Serial.read();
   if (inByte == 'h')  // "h" command
   {
     unsigned long i;
     for(i=0;i<512;i++)
     buffer[i]=12;
      for(i=400000;i<500001;i++)
  {
     
      response = sd.writeblock(i);
     
      if (i%1000 == 0)
       Serial.println(i);
      if (response !=0)
    {
      Serial.println(response * 256);
      Serial.println(i);
    }
  }
      for(i=0;i<512;i++)
      buffer[i]=1;
     response = sd.readblock(500000);
     Serial.println(response * 256);
     for(i=0; i<10; i++) //read 512 bytes
     Serial.println(buffer[i] * 256);
   } //end of received "h"
  }//end of serial available  
}//end of loop


This is my .h file :

Code: [Select]
/* Card type: Ver2.00 or later Standard Capacity SD Memory Card
             1.0 and 2.0 GB cards purchased in 2009 work well.
  Usage:  Must have global variable.
             volatile unsigned char buffer[512];
          Function calls.
             unsigned char error = SDCARD.readblock(unsigned long n);
             unsigned char error = SDCARD.writeblock(unsigned long n);
           error is 0 for correct operation
           read copies the 512 bytes from sector n to buffer.
           write copies the 512 bytes from buffer to the sector n.
  References: SD Specifications. Part 1. Physical Layer Simplified Specification
              Version 2.00 September 25, 2006 SD Group.
              http://www.sdcard.org
  Code examples:  http://www.sensor-networks.org/index.php?page=0827727742
                  http://www.avrfreaks.net   search "sd card"
  Operation:  The code reads/writes direct to the sectors on the sd card.
              It does not use a FAT. If the card has been formatted the
              FAT at the lowest sectors and files at the higher sectors
              can be written over.
              The card is not damaged but will need to be reformatted at
              the lowest level to be used by windows/linux.
  Timing:  readblock or writeblock takes 44 msec.
  Improvement: Could initialize so that can use version 1 sd and hc sd.
               Instead of CMD1 need to use CMD8, CMD58 and CMD41.
*/
#ifndef SDCARD_h
#define SDCARD_h

#define setupSPI SPCR = 0x53; //Master mode, MSB first, SCK phase low, SCK idle low, clock/64
#define deselectSPI SPCR = 0x00;  //deselect SPI after read write block
#define clearSPI  SPSR = 0x00; // clear SPI interupt bit
#define setupDDRB DDRB |= 0x2c;  //set SS as output for cs
#define selectSDCARD PORTB &= ~0x04;  //set the SS to 0 to select the sd card
#define deselectSDCARD PORTB |= 0x04;  //set the SS to 1 to deselect the sd card

#include "WProgram.h"

class SDCARD
{
public:
unsigned char readblock(unsigned long Rstartblock);
unsigned char writeblock(unsigned long Wstartblock);

private:
unsigned char SD_reset(void);
unsigned char SD_sendCommand(unsigned char cmd, unsigned long arg);
unsigned char SPI_transmit(unsigned char data);

};//end of class SDCARD

#endif


This is my .cpp file:

Code: [Select]

#include "WProgram.h"
#include "SDCARD.h"

extern volatile unsigned char buffer[512]; //caller defines buffer

unsigned char SDCARD::SD_reset(void)
{
unsigned char response;
unsigned int retry = 0;
setupDDRB  
setupSPI
clearSPI

do
{
  response = SD_sendCommand(0, 0); //send 'reset & go idle' command
  if(++retry>254){
  return 1;}  
} while(response != 0x01);

retry=0;
do
{
   response = SD_sendCommand(1, 0); //activate card's initialization process
   if(++retry>254){
   return 2;}  
}while(response);
//CRC disabled in SPI mode so we will keep it that way.
retry = 0;
do
{  
 response = SD_sendCommand(16, 512); //set block size to 512
 if(++retry>10)
 return 8;            //time out  
}while (response);
return 0;
}//end of SD_reset function

unsigned char SDCARD::readblock(unsigned long Rstartblock)
{
unsigned char response, saveDDRB;
unsigned int i, retry=0;
saveDDRB = DDRB;  // save current DDRB
response = SD_reset();   // reset the sd card
if (response != 0 )
{
DDRB = saveDDRB;  //restore the DDRB
deselectSPI
return response;  //board wont reset return error
}
do
{
response = SD_sendCommand(17, Rstartblock<<9); //read a Block command
//block address converted to starting address of 512 byte Block
if(++retry>10)
{
 DDRB = saveDDRB;  //restore the DDRB
 deselectSPI
 return 3;
}
}while (response);
selectSDCARD  //set the SS to 0 to select the sd card
retry = 0;

while(SPI_transmit(0xff) != 0xfe) //wait for start block token 0xfe
{  
 if(retry++ > 600)
 {
   deselectSPI
   DDRB = saveDDRB;  //restore the DDRB
   deselectSPI  
   return 4; //return if time-out
 }//end time out for token
}//end receive token
for(i=0; i<512; i++) //read 512 bytes
 buffer[i] = SPI_transmit(0xff);
SPI_transmit(0xff); //receive incoming CRC (16-bit), CRC is ignored here
SPI_transmit(0xff);
SPI_transmit(0xff); //extra 8 clock pulses
deselectSDCARD  //set the SS to 1 to deselect the sd card
DDRB = saveDDRB;  //restore the DDRB
deselectSPI
return 0;
}//end of read block

unsigned char SDCARD::writeblock(unsigned long Wstartblock)
{
unsigned char response, saveDDRB;
unsigned int i, retry=0;
saveDDRB = DDRB;  // save current DDRB
response = SD_reset();   // reset the sd card
if (response != 0 )
{
DDRB = saveDDRB;  //restore the DDRB
deselectSPI
return response;  //board wont reset return error
}
do
{
response = SD_sendCommand(24, Wstartblock<<9); //write a Block command
if(++retry>10)
{
 DDRB = saveDDRB;  //restore the DDRB
 deselectSPI
return 5;            //time out
}
}while (response);
selectSDCARD  //set the SS to 0 to select the sd card
SPI_transmit(0xfe);     //Send start block token 0xfe (0x11111110)
for(i=0; i<512; i++)    //send 512 bytes data
 SPI_transmit(buffer[i]);
SPI_transmit(0xff);     //transmit dummy CRC (16-bit), CRC is ignored here
SPI_transmit(0xff);

response = SPI_transmit(0xff);
/*Every data block written to the card will be acknowledged by a data response token. It is one byte long
and has the following format:
x x x 0 Status 1
The meaning of the status bits is defined as follows:
010 - Data accepted.
101 - Data rejected due to a CRC error.
110 - Data Rejected due to a Write Error*/
if( (response & 0x1f) != 0x05)
{  
 deselectSDCARD              
 DDRB = saveDDRB;  //restore the DDRB
 deselectSPI
 return 6;
}

while(!SPI_transmit(0xff)) //wait for SD card to complete writing and get idle
if(retry++ > 60000)
{
DDRB = saveDDRB;  //restore the DDRB
deselectSPI
deselectSDCARD
return 7;
}
deselectSDCARD
DDRB = saveDDRB;  //restore the DDRB
deselectSPI
return 0;
}//end of write a block of data

unsigned char SDCARD::SD_sendCommand(unsigned char cmd, unsigned long arg)
{

unsigned char response, retry=0, i;
for(i=0; i<10; i++) //presend calls
SPI_transmit(0xff);  //need wakeup calls
selectSDCARD  //set the SS to 0 to select the sd card
SPI_transmit(0xff);  //wakeup call
SPI_transmit(cmd | 0x40); //send command, first two bits always '01'
SPI_transmit(arg>>24);
SPI_transmit(arg>>16);
SPI_transmit(arg>>8);
SPI_transmit(arg);
SPI_transmit(0x95);  //crc does not matter except for cmd0

while((response = SPI_transmit(0xff)) == 0xff) //wait response
  if(retry++ > 254) break; //time out error

deselectSDCARD  //set the SS to 1 to deselect the sd card
return response; //return state
}

unsigned char SDCARD::SPI_transmit(unsigned char data)
{
// Start transmission
SPDR = data;
// Wait for transmission complete
while(!(SPSR & (1<<SPIF)));
data = SPDR;
return(data);
}



I had to take out the .cpp comments to fit it on the reply.

I hope this is enough information to let you see what I'm up to.

Coding Badly

Sorry about the slow reply...

Quote
The compiler says compiling but gives an error message
couldn't determine program size:
I tried as much as I can think of..........any hints ?


Quote
Not without more details.


Dang!  We should have searched the forum first...
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1225145000

For what it's worth I compiled the source code you provided using the Arduino Mega board and had no errors.  I don't think you need to worry about the error message.

carl47

Thanks a lot.

When I got the compile errors I did not even try to upload
the program.

After reading that forum page I tried an upload ..... no errors!

Now that the hex file has been produced in the applet it seems
to have changed everything and I can compile now and never
get an error.

It seems that they have not fixed that bug even in 0016.

I dont like seeing that red at the bottom but it seems for:-
"couldn't determine program size"
It does not matter.

Since I wrote above I've tried 0017. No problems at all they have
fixed the bug. Infact they handle the libraries in a different
way. There are no .o files in the library now so they must
be compiling them as needed.

By the way is it possible to do a keyword search of the forum
pages?
:)

Coding Badly

Quote
By the way is it possible to do a keyword search of the forum pages?


This is what I use...

http://www.google.com/search?q=%5Bsearch-terms-go-here%5D+site%3Aarduino.cc

carl47

Thanks for that.

I was unaware you could do a keyword search of
a site using google.

Google is certainly your friend.

Coding Badly

I should have also mentioned that you can restrict the search to just the Arduino forums using something like this...

http://www.google.com/search?q=%5Bsearch-terms-go-here%5D+site%3Aarduino.cc/cgi-bin/yabb2/YaBB.pl

Quote
Google is certainly your friend


:)

carl47

Thanks that will cut down the responses nicely.

Go Up