CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

interfacing sd card with 16f877a
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
gopalakrishnan



Joined: 18 Jun 2010
Posts: 25

View user's profile Send private message

interfacing sd card with 16f877a
PostPosted: Wed Sep 29, 2010 12:09 am     Reply with quote

hai to all

We are trying to interface micro sd card with 16f877A, using compiler version of 3.098 ccs c. We tried a simple code by sending command 0 and command 1 through spi of the sd card and display its response in the lcd.
We use two transistor as a level shifter from SDO of the pic to MOSI and other for MISO of the sd card to the SDI, then we use potential divider across the SCK of the pic.
My problem is I am always receiving a garbage character and 00 in the display as the response code.
Second thing is how to calculate CRC for other commands? Then how to read and write a block of data?
Finally our code is:
Code:

 #include "D:\transinnova\temp\spi\spi_test.h"

#if defined(__PCM__)

#include <stdio.h>
#include <string.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use delay(clock=4000000)
#use standard_io(B)
#use standard_io(C)
#use standard_io(D)


#define LCD_ENABLE_PIN PIN_B0
#define LCD_RS_PIN PIN_B2
#define LCD_RW_PIN PIN_B1
#define LCD_TYPE 2

#define SPI_SDI PIN_C4  //PIN 23
#define SPI_SDO PIN_C5  //PIN 24
#define SPI_SCK PIN_C3  //PIN 18
#define SPI_SS PIN_A5   //PIN 7

void lcd_init();
void lcd_cmd(cmd);               
void lcd_data(data);
void nibbel_split(split);
//int a[]={'T','r','a','n','s','i','n','n','o','v','a'};

 int cmd0[]={0x40,0x00,0x00,0x00,0x00,0x95};
 int cmd1[]={0x41,0x00,0x00,0x00,0x00};
 unsigned char cmd,data;
 int SDresponse,i;

void main()
{

  set_tris_b(0x00);
  set_tris_d(0x00);
  set_tris_c(0x10);
  lcd_init();
  setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_16);
 
  output_high(PIN_A5);
  output_high(PIN_C5);
 
  for(i=0;i<=73;i++)
  {
    output_low(PIN_C3);
    output_high(PIN_C3);
  }
 
  for(i=0;i<=5;i++)
  {
    output_low(PIN_A5);
    delay_us(100);
    spi_write(cmd0[i]);
    spi_write(cmd1[i]);
  }
     
      lcd_data('s');
      SDresponse= spi_read();
      nibbel_split(SDresponse); //function to split upper and lower nibbel
   
      output_high(PIN_A5);
}

 void nibbel_split(int DataIn)
 {
   
    int DDLN,DDUN,LN,UN;
    LN= (DataIn & 0x0F);
    if(LN<=0X09){DDLN= LN+(0x30);}
    else{DDLN= LN+(0x37);}
    DataIn = swap(DataIn);
    UN= (DataIn & 0x0F);
    if(UN<=0X09){DDUN= UN+(0x30);}
    else{DDUN= UN+(0x37);}
    lcd_data(DDUN);
    lcd_data(DDLN);
    return;
 }   

void lcd_init()
   {
      cmd=0x38;
      lcd_cmd(cmd);
      delay_ms(250);
      cmd=0x0E;
      lcd_cmd(cmd);
      delay_ms(250);   
      cmd=0x01;
      lcd_cmd(cmd);
      delay_ms(250);     
      cmd=0x06;
      lcd_cmd(cmd);
      delay_ms(250);
      lcd_data(data);
      return;
   }
   void lcd_cmd(cmd)
   {
      output_d(cmd);
      output_low(PIN_b2);//rs     
      output_low(PIN_b1);//read write
      output_high(PIN_b0);
      delay_ms(250);
      output_low(PIN_b0);//enabel
      return;
   }
   void lcd_data(data)
   {
      output_d(data);
      output_high(PIN_b2);//rs     
      output_low(PIN_b1);//read write
      output_high(PIN_b0);
      delay_ms(250);
      output_low(PIN_b0);//enabel
      delay_ms(250);
      return;
     
   }

Thanks in advance.

with regards
K.gopalakrishnan
arunb



Joined: 08 Sep 2003
Posts: 492
Location: India

View user's profile Send private message Send e-mail

PostPosted: Wed Sep 29, 2010 1:17 am     Reply with quote

You need to use a micro-controller with much more RAM, the micro SD card sends and receives data in blocks of 512 bytes, so the micro-controller must be able to store 512 bytes in the RAM.

There are two options

1. Upgrade to a mcu of higher RAM capacity. The 18F4620 is a pin-compatible mcu that can replace the 16F877A. It has the same no. of pins, better features, more RAM and ROM, and can also work at faster speed.

The 18F4450 is another device that is pin compatible and also has USB.
You also need the PCH version of the CCS compiler to compile the 18F devices.

2. Use a FRAM (Flash RAM) to buffer the data for the SD card. The FRAM is fast and has almost unlimited read/write cycles compared to an EEPROM.

The FM25256 (manufactured by Ramtron electronics) used to be quite popular, but you have to check if newer devices are available.

thanks
a
gopalakrishnan



Joined: 18 Jun 2010
Posts: 25

View user's profile Send private message

regarding sd card
PostPosted: Mon Oct 04, 2010 5:58 am     Reply with quote

thank you arun for your valuable sugession i decided to change my ic. you specified to replace 18f4620 instead of 16f877a. where as 18f4620 is not availabel in near by where as 18f4520 is available shell i make use of it. when i go through its specification they vary only in the ram memory. all those things remain same as that of 16f877a. would you reply me.

how to read and write into the card do you have any resource regarding that.

with regards
k.gopalakrishnan
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Mon Oct 04, 2010 6:53 am     Reply with quote

The change your pic device to one with lots of ram is the correct way to go.
Sectors are 512 bytes. A write or a read modify of a sector will need ram. However with the SPI mode a read can be as little as one byte for MMC /SD or byte addressing. SDHC and cards over 4gb ( there were some cards that are 4gb that use byte addressing) use sector addressing so the 512 byte applies to read as well. Originally these cards were considered as replacement memory so were byte addressed. The 512 byte disk type sector restriction always was there ( flash has block writes ) but you could address a single byte. Now the cards are considered as flash drives and are addressed as sectors and are labeled SDHC. Now with a sector read your PIC still gets it a byte at a time so with extra pic code you could filter down to the byte or bytes you want and avoid reading all of the 512 bytes into ram
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Mon Oct 04, 2010 8:17 am     Reply with quote

I would suggest using an external memory chip.. eeprom like the 25lc512
or something along those lines.

You could fill it up with simple one byte writes and modify individual bytes as well.

Once its filled you could write from eeprom to mmc
using the eeprom as your 512Byte buffer.

Use spi software for the eeprom and spi hardware for the mmc.

If you are doing a logger, or have unreliable power supply, or whatever issue, your data buffer won't be lost.


Just my two cents....

Bt maybe you can't read from an eeprom and write to the mmc at the same time but I doubt you couldn't.

Doing the 512 byte transfer would take some time though.

I'm building a logger myself and plan to use this method.
If anybody has any objections to this method I would greatly appreciate your comments.
_________________
CCS PCM 5.078 & CCS PCH 5.093
arunb



Joined: 08 Sep 2003
Posts: 492
Location: India

View user's profile Send private message Send e-mail

RE:
PostPosted: Mon Oct 04, 2010 10:14 pm     Reply with quote

An EEPROM has limited write cycles, also to write to the EEPROM, the data location is erased first and then written, so there is some time delay involved while writing to an EEPROM.

For a buffer a FRAM is a better solution than the EEPROM.

So will the datalogger log events or continously sample data at pre-determined intervals.

The 18F4520 looks OK, it has sufficient RAM to handle the sd card.

Quote:
how to read and write into the card do you have any resource regarding that.


Read the sdcard driver code in the CCS folder, I used these to handle all the read/write operations.

In my project I declared an array (512 bytes long) that acted as a buffer for the SD card, when writing to the card, the array would be filled with the desired data and then written as a block.

To edit data, a block of data would have to read into the array, the relevant bytes modified and the re-written to the card.

For more sophisticated operations the FAT16 file system could also be implemented. The Code Library section of this forum lists many drivers that could be used.

thanks
a
gopalakrishnan



Joined: 18 Jun 2010
Posts: 25

View user's profile Send private message

regarding sd card
PostPosted: Tue Oct 05, 2010 7:23 am     Reply with quote

hai thank you for your reply.

Kindly clarify me my understanding is right.

When command 0 is sent through spi_write() function for this sd card will response it as 00. Is it so. I read this response through sd_read and display it through lcd.

I do this simple test to ensure myself my understanding is write or wrong.

#include <mmcsd.c> is this a library function available for 18f4520? And functions like mmcsd_init(). Like that for read and write. Can I directly make use of it for intializing the sd card?

Where can I find a resource for interfacing the sd card with pic? You posted sd card driver folder in ccs. Where it is?

kindly reply me
k.gopalakrishnan
arunb



Joined: 08 Sep 2003
Posts: 492
Location: India

View user's profile Send private message Send e-mail

RE:
PostPosted: Wed Oct 06, 2010 12:41 am     Reply with quote

The mmcsd.c driver worked perfectly for me. I used the block read/write and init functions only.

thanks
a
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Oct 06, 2010 2:51 am     Reply with quote

Quote:
You posted sd card driver folder in ccs. Where it is?
C:\Program Files\PICC\drivers

There are two drivers:
mmc_spi.c: this is using the older SPI functions (setup_spi() ). Proven technology.

sdmmc.c: Is using the newer '#use spi' functions. This is more flexible as it allows emulation of SPI on other pins than the designated SPI hardware pins but last time I checked it in the old version v4.077 there were some errors. (using a wrong SPI mode).
gopalakrishnan



Joined: 18 Jun 2010
Posts: 25

View user's profile Send private message

regarding sd card
PostPosted: Mon Oct 11, 2010 4:58 am     Reply with quote

hai thanks for your reply

I go through the driver files. I tried to understand it. It is too difficult. How you people make understanding it? Is there any article or techinical forum? Kindly help me.

with regards
k.gopalakrishnan
arunb



Joined: 08 Sep 2003
Posts: 492
Location: India

View user's profile Send private message Send e-mail

RE:
PostPosted: Mon Oct 11, 2010 11:30 pm     Reply with quote

Read the specification of the sd card first. In particular read the portions that mention how the card can be addressed, the initialisation procedures, the protocol of the SPI communication used by the card.

Search for the specs using google and download them.

The driver code has a debug facility that is very useful. You need to connect your hardware to the RS 232 port of the computer. The debug facility prints out all the error/return values that are generated while the various procedures such as initialisation, block write, block read are performed.

For your information the driver code in the CCS folder worked out of the box for me I just used the debug feature of the code to understand what was going on.

thank
a
gopalakrishnan



Joined: 18 Jun 2010
Posts: 25

View user's profile Send private message

regarding interfacing sd card
PostPosted: Mon Oct 18, 2010 8:29 am     Reply with quote

hai to all

I entirely changed my program. As far as my hardware is concern
I am using two transistors for level shifting purposes one from SDO to MOSI of sd card where as other for MISO of the sd card to SDI. Then I use potential divider between clk and ss pin. This my hardware connection is about.

Just I want to write my string in the specified location and get back it through read command is my objective. Is wish to see the data in the display, but I always see the blank display. Kindly suggest me some ideas and check my code. Am I in the right path? Kindly guide me.

My code is
Code:

#include "D:\transinnova\temp\spi_stream\spi_stream.h"

#if defined(__PCM__)
#endif
#include <stdio.h>
#include <string.h>
#include <mmcsd.c>
#include <input.c>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use delay(clock=4000000)
#use standard_io(B)
#use standard_io(C)
#use standard_io(D)


#define LCD_ENABLE_PIN PIN_B0
#define LCD_RS_PIN PIN_B2
#define LCD_RW_PIN PIN_B1
#define LCD_TYPE 2

#define SPI_SDI PIN_C4  //PIN 23
#define SPI_SDO PIN_C5  //PIN 24
#define SPI_SCK PIN_C3  //PIN 18
#define SPI_SS  PIN_A5   //PIN 07

#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)

void lcd_init();
void lcd_cmd(cmd);               
void lcd_data(data);
void nibbel_split(unsigned long DataIn);

int mmc_init();
int mmc_response(unsigned char response);
int mmc_get_status();
int mmc_write_block(unsigned long block_number);
int mmc_read_block(unsigned long block_number);

 // int cmd0[]={0x40,0x00,0x00,0x00,0x00,0x95};
  // int cmd08[]={0x48,0x00,0x00,0x00,0x00,0xFF};
  //  int amcd41[]={0x69,0x00,0x00,0x00,0x00,0xFF};
   // int cmd55[]={0X77,0x00,0x00,0x00,0x00,0xFF};
   // int cmd58[]={0x7A,0x00,0x00,0x00,0x00,0xFF};
 
 unsigned char cmd,data;
 int i,j=0;
 int res,rcvdat;
 char send_data[]={"TRANSINNOVA INSTRUMENTS PVT LTD"};
 int read[32];
 int DDLN,DDUN,LN,UN;
 
void main()
{

  set_tris_b(0x00);
  set_tris_d(0x00);
  set_tris_c(0x10);
  lcd_init();
 
 

 setup_spi(SPI_MASTER|SPI_MODE_0|SPI_CLK_DIV_16);// cmd to setup spi mode
 
  mmc_init();
  mmc_get_status();
  mmc_write_block(0x0002);
  mmc_read_block(0x0002);       
}


int mmc_init()
{
 output_high(PIN_A5); // set high slave select signal before sending cmd0
 output_high(PIN_C5);
   
   for(i=0;i<10;i++)                       // initialise the MMC card into SPI mode by sending clks on
{
        SPI_WRITE(0xFF);
}
  output_low(PIN_A5);

   spi_write(0x40);
   spi_write(0x00);
   spi_write(0x00);
   spi_write(0x00);
   spi_write(0x00);
   spi_write(0x95);
 
if( mmc_response(0x01)==1);
 return 1 ;      // if = 1 then there was a timeout waiting for 0x01 from the mmc
i = 0;

while((i < 255) && (mmc_response(0x00)==1))     // must keep sending command if response
{
        SPI_WRITE(0x69);                // send sd command 41 to bring out of idle state
        SPI_WRITE(0x00);                // all the arguments are 0x00 for command one
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
        i++;
}
if(i >= 254) return 1;                   // if >= 254 then there was a timeout waiting for 0x00 from the mmc
 output_high(PIN_A5);

SPI_WRITE(0xFF);
output_low(PIN_A5);

        SPI_WRITE(0x77);                //  cmd 55 Notifies the card that the next command is an
                                       //  application specific command rather than a standard command.
                                                                             
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);                // high block length bits - 512 bytes
        SPI_WRITE(0x00);                // low block length bits
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF

if((mmc_response(0x00))==1) return 1 ;
 output_high(PIN_A5);
return 0 ;

OUTPUT_HIGH(PIN_A5);                    // set SS = 1 (off)

SPI_WRITE(0xFF);                        // extra clocks to allow mmc to finish off what it is doing

OUTPUT_LOW(PIN_A5);                     // set SS = 0 (on)

        SPI_WRITE(0x50);                // send mmc command one to bring out of idle state
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x02);                // high block length bits - 512 bytes
        SPI_WRITE(0x00);                // low block length bits
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF

if((mmc_response(0x00))==1) return 1;
OUTPUT_HIGH(PIN_A5);            // set SS = 1 (off)

return 0;
}


int mmc_read_block(unsigned long block_number)
{
unsigned long i;
unsigned long varh,varl,adrhigh,adrlow;

varl=(block_number&0x003F);
nibbel_split(varl);
adrhigh=UN;
adrlow=LN;

varh=(block_number&0xFFC0);
nibbel_split(varh);



OUTPUT_LOW(PIN_C2);                       // set SS = 0 (on)

        SPI_WRITE(0x51);
        SPI_WRITE(UN);      // send mmc read single block command
        SPI_WRITE(LN);                 // arguments are address
        SPI_WRITE(adrlow);
        SPI_WRITE(0x00);
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF

if((mmc_response(0x00))==1) return 1;   // if mmc_response returns 1 then we failed to get a 0x00 response (affirmative)



if((mmc_response(0xFE))==1) return 1;   // wait for data token


        for(i=0;i<512;i++)
        {
               read[i] =SPI_READ(0xFF);               // we should now receive 512 bytes
               nibbel_split(read[i]);
        }

SPI_READ(0xFF);                 // CRC bytes that are not needed
SPI_READ(0xFF);

OUTPUT_HIGH(PIN_A5);            // set SS = 1 (off)
SPI_WRITE(0xFF);                // give mmc the clocks it needs to finish off


return 0;
}


int mmc_get_status()
{

OUTPUT_LOW(PIN_A5);              // set SS = 0 (on)

        SPI_WRITE(0x58);       // send mmc command one to bring out of idle state
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);   
        SPI_WRITE(0x00);    // always zero as mulitples of 512
        SPI_WRITE(0xFF);   // checksum is no longer required but we always send 0xFF

OUTPUT_HIGH(PIN_A5);     // set SS = 1 (off)
return 0;
}


int mmc_write_block(unsigned long block_number)
{
unsigned long i;
unsigned long varh,varl,adrhigh,adrlow;

varl=(block_number&0x003F);
nibbel_split(varl);
adrhigh=UN;
adrlow=LN;

varh=(block_number&0xFFC0);         // block size has been set in mmc_init()
nibbel_split(varh);

OUTPUT_LOW(PIN_A5);                     // set SS = 0 (on)

        SPI_WRITE(0x58);                // send mmc write block
        SPI_WRITE(UN);
        SPI_WRITE(LN);
        SPI_WRITE(adrlow);
        SPI_WRITE(0x00);             // always zero as mulitples of 512
        SPI_WRITE(0xFF);            // checksum is no longer required but we always send 0xFF

if((mmc_response(0x00))==1) return 1;


SPI_WRITE(0xFE);                // send data token

for(i=0;i<512;i++)
{

SPI_WRITE(send_data[i]);     // send data

}

SPI_WRITE(0xFF);        // dummy CRC
SPI_WRITE(0xFF);

if((SPI_READ(0xFF)&0x0F)!=0x05) return 1;

OUTPUT_HIGH(PIN_A5);       // set SS = 1 (off)
return 0;
}

int mmc_response(unsigned int response)
{
        unsigned long count = 0xFFFF;             
        rcvdat=SPI_READ(0xFF);
      //  nibbel_split(rcvdat);
        while((rcvdat) != response && --count > 0);
       // lcd_data(rcvdat);
        if(count==0) return 1;   // loop was exited due to timeout
        else return 0;          // loop was exited before timeout
}



 void nibbel_split(unsigned long DataIn)// function to split upper and lower nibbel of the received data
 {
   
   
    LN= (DataIn & 0x0F);
    if(LN<=0X09){DDLN= LN+(0x30);}
    else{DDLN= LN+(0x37);}
    DataIn = swap(DataIn);
    UN= (DataIn & 0x0F);
    if(UN<=0X09){DDUN= UN+(0x30);}
    else{DDUN= UN+(0x37);}
     lcd_data(DDLN);
     lcd_data(DDUN);
    return;
 }
gopalakrishnan



Joined: 18 Jun 2010
Posts: 25

View user's profile Send private message

regarding sd card
PostPosted: Fri Oct 22, 2010 8:37 am     Reply with quote

[img]http://C:\Users\transinnova\Desktop[/img]

I am interfacing my micro sd card with the above circuit diagram. I am initializing my sd card with the following sample code, i am displaying the response in my lcd. According to the code i am expecting blank display where as it shows one. which means it is not initialized or card is not accepted.

my code is:
Code:

#if defined(__PCM__)
#if defined(__PCH__)
#endif
#endif

#include <stdio.h>
#include <string.h>
#include <mmcsd.c>
#include <input.c>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use delay(clock=4000000)
#use standard_io(B)
#use standard_io(C)
#use standard_io(D)


#define LCD_ENABLE_PIN PIN_B0
#define LCD_RS_PIN PIN_B2
#define LCD_RW_PIN PIN_B1
#define LCD_TYPE 2

#define SPI_SDI PIN_C4  //PIN 23
#define SPI_SDO PIN_C5  //PIN 24
#define SPI_SCK PIN_C3  //PIN 18
#define SPI_SS  PIN_C2   //PIN 07

#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)

void lcd_init();
void lcd_cmd(cmd);               
void lcd_data(data);
void nibbel_split(unsigned long DataIn);

int mmc_init();
int mmc_response(unsigned char response);
int mmc_get_status();
int mmc_write_block(unsigned long block_number);
int mmc_read_block(unsigned long block_number);

 unsigned char cmd,data;
 int i,j=0;
 int res,rcvdat;
 char send_data[]={"TRANSINNOVA INSTRUMENTS PVT LTD"};
 int read[32];
 int DDLN,DDUN,LN,UN;
  int errvalue;
void main()
{

  set_tris_b(0x00);
  set_tris_d(0x00);
  set_tris_c(0x10);

  lcd_init();

 // cmd to setup spi mode

  lcd_data((mmc_init()+0x30));
    output_low(PIN_C2);
 
//  mmc_get_status();
 // mmc_write_block(0x0002);
  //mmc_read_block(0x0002);       
}


int mmc_init()
{
setup_spi(SPI_MASTER|SPI_MODE_0|SPI_CLK_DIV_16);

output_high(PIN_C2); // set high slave select signal before sending cmd0
output_high(PIN_C5);
   
for(i=0;i<10;i++) // initialise the MMC card into SPI mode by sending clks on
{
        SPI_WRITE(0xFF);
}

  output_low(PIN_C2);

       spi_write(0x40);
       spi_write(0x00);
       spi_write(0x00);
       spi_write(0x00);
       spi_write(0x00);
       spi_write(0x95);

if( mmc_response(0x01)==1);
 return 1 ;
}
 
 /*          // if = 1 then there was a timeout waiting for 0x01 from the mmc
i = 0;

while((i < 255) && (mmc_response(0x00)==1))     // must keep sending command if response
{
        SPI_WRITE(0x41);                // send sd command 41 to bring out of idle state
        SPI_WRITE(0x00);                // all the arguments are 0x00 for command one
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF
        i++;
}
if(i >= 254) return 2;                   // if >= 254 then there was a timeout waiting for 0x00 from the mmc
 

OUTPUT_HIGH(PIN_C2);                    // set SS = 1 (off)

SPI_WRITE(0xFF);                        // extra clocks to allow mmc to finish off what it is doing

OUTPUT_LOW(PIN_C2);                     // set SS = 0 (on)

        SPI_WRITE(0x50);                // send mmc command one to bring out of idle state
        SPI_WRITE(0x00);
        SPI_WRITE(0x00);
        SPI_WRITE(0x02);                // high block length bits - 512 bytes
        SPI_WRITE(0x00);                // low block length bits
        SPI_WRITE(0xFF);                // checksum is no longer required but we always send 0xFF

if((mmc_response(0x00))==1) return 3;
OUTPUT_HIGH(PIN_C2);            // set SS = 1 (off)

return 0;
}

int mmc_response(unsigned int response)
{
        unsigned long count = 0xFFFF;
               
        while(SPI_READ(0xFF) != response && --count > 0);
        if(count==0) return 1;   // loop was exited due to timeout
        else return 0;         // loop was exited before timeout
}

Kindly help me to get out of this.

Thanks
with regards
K.gopalakrishnan
gopalakrishnan



Joined: 18 Jun 2010
Posts: 25

View user's profile Send private message

regarding inserting my circuit
PostPosted: Sat Oct 23, 2010 5:14 am     Reply with quote

i want to know how to insert circit diagrams in this forum.

kindly help me


with regards
k.gopalakrishnan
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Oct 25, 2010 2:49 am     Reply with quote

First comment is that you should try to put more effort in writing clean code. Of course every programmer has his/hers own style of programming and sometimes you want to cut corners to make a quick test, but when you run into problems it helps a lot to clean up your code.
For example your code has sloppy indentation; lines that belong together have different number of spaces in front of them.

Code:
 // cmd to setup spi mode

  lcd_data((mmc_init()+0x30));
This is another example of dirty programming, the comments and code do not match. Your code has more of these 'errors'.
You may think that I'm making a big thing about the details, and yes I am but for good reason: computers only do what you tell them to do, this is often not the same as what you want them to do.

Now we come at a real bug, or actually two:
Code:
if( mmc_response(0x01)==1);
 return 1;
}
1) At the end of the first line is a ';' that shouldn't be there. Now this ';' is executed as an 'empty statement', so whatever the outcome of the test, nothing will be done.
2) When the init routine runs correct you want it to return a zero, but this code is missing.

Here is the corrected code:
Code:
if( mmc_response(0x01)==1)   //  <--  note the removed ';' !!!!!
   return 1;
else
   return 0;
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group