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 CCS Technical Support

First try at MMC/SD, seeking for help

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

First try at MMC/SD, seeking for help
PostPosted: Mon Jun 26, 2006 10:40 am     Reply with quote

Hello all,

I am starting my SD card journey and I think I�ll need a little help from you.

After all the readings I tried this code to see what I can send to the card and what I�ll get from it.

The card doesn�t seem to initialize and I get only 0xFF from it.

The code:

Code:

#include <18f452.h>
#zero_ram
#fuses H4, NOWDT, PUT, NOLVP
#use delay( clock = 40000000 )
#use rs232( baud=4800, xmit=PIN_C6, rcv=PIN_C7, ERRORS )

#define SCK PIN_B0
#define SDO PIN_B2
#define SDI PIN_B1
#define _CS PIN_B3

/* SanDisk�s MultiMediaCards and RS-MultiMediaCards clock data in on the rising edge and out on the falling edge
*/
unsigned char SPI( unsigned char outchar )
{
      unsigned char i, inchar;

      for( i = 0; i < 8; i++ )
         {
           output_bit( SDO, shift_left( &outchar, 1, 0 ) );
           delay_ms(1);
           output_high( SCK );
           delay_ms(1);
           output_low( SCK );
           delay_ms(1);
           shift_left( &inchar, 1, input( SDI ) );
           delay_ms(1);
         }

      return( inchar );
}

/*
*/
unsigned char command( unsigned char befF, unsigned long AdrH, unsigned  long AdrL, unsigned char befH )
{
        SPI( 0xFF );
        SPI( befF );
        SPI( AdrH >>8 );
        SPI( AdrH );
        SPI( AdrL >>8 );
        SPI( AdrL );
        SPI( befH );
        SPI( 0xFF );
 return SPI( 0xFF );      // Return with the response
}

void main(void)
{
   char i;

   printf("\n\rSequence start\n\r");

   delay_ms( 1000 );

   port_b_pullups(true);

   set_tris_c(0b10000000);    // sck rc3-0, sdo rc5-0, CS rc2-0.

   output_high  ( _CS );
   output_high  ( SCK );
   output_high  ( SDO );
   output_float ( SDI );

   delay_ms( 150 );

   for( i = 0; i < 10; i++ )
      {
        printf("80 clocks init try: %d response: %x\n\r", i, SPI( 0xFF ) ); // 10*8=80 clocks
      }

   delay_ms( 150 );

   output_low( _CS );

   printf("Command 0x40 response: %x\n\r", command( 0x40, 0, 0, 0x95 ) );

   output_high( _CS );

   output_low( _CS );

   printf("Command 0x41 response: %x\n\r", command( 0x41, 0, 0, 0x01 ) );

   output_high( _CS );

   printf("Sequence end\n\r");

// printf("%x\n\r",spi(0)); // When sdi and sdo are shorted I see correct data return
// printf("%x\n\r",spi(1));
// printf("%x\n\r",spi(2));
// printf("%x\n\r",spi(3));

   while(1);
}


The output:
Code:

Sequence start
80 clocks init try: 0 response: ff
80 clocks init try: 1 response: ff
80 clocks init try: 2 response: ff
80 clocks init try: 3 response: ff
80 clocks init try: 4 response: ff
80 clocks init try: 5 response: ff
80 clocks init try: 6 response: ff
80 clocks init try: 7 response: ff
80 clocks init try: 8 response: ff
80 clocks init try: 9 response: ff
Command 0x40 response: ff
Command 0x41 response: ff
Sequence end


Thank you.
ckielstra



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

View user's profile Send private message

PostPosted: Mon Jun 26, 2006 12:54 pm     Reply with quote

Code:
   set_tris_c(0b10000000);    // sck rc3-0, sdo rc5-0, CS rc2-0.
The set_tris function have to be used in combination with the #use fast_io or #use fixed_io. Without these declarations the compiler will automatically set the TRIS registers at every output_xxx call, possibly changing your settings and adding overhead.

Code:
#define SCK PIN_B0
#define SDO PIN_B2
#define SDI PIN_B1
#define _CS PIN_B3
This is in conflict with your TRIS settings. Fix it.

Quote:
delay_ms( 150 );

for( i = 0; i < 10; i++ )
{
printf("80 clocks init try: %d response: %x\n\r", i, SPI( 0xFF ) ); // 10*8=80 clocks
}

delay_ms( 150 );
Your text is confusing, this code does not initialize the card but is part of the specifications to allow the card to startup and do some internal housekeepings.
The delay functions are not needed, only slowing down your program startup.
Better to get rid of the printf, it doesn't give extra info as the card is not selected yet and will always show 0xFF.

You initialize SCK at a high level, but in the SPI() function your clock start pule is a rising edge. This is not going to work.

Why are you creating your own SPI function when there is a hardware module in your PIC18F452 that can do the same much more efficiently? You can then also use the CCS supplied and tested SPI functions.
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

PostPosted: Mon Jun 26, 2006 5:48 pm     Reply with quote

I know there are many mistakes, but I am trying Embarassed

The reason I am using a software SPI is because I want to have generic code that can work on any other micro.

Also this project in particular will use hardware i2c and I need speed here.

The prinft's were to see what was coming back from the card.

Sorry I missed some comments that were not to be there, the sd card is really on portb.

In the only datasheet I've found about the sd specs, I couldn't get any information about the correct timing and clock polarity.
ckielstra



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

View user's profile Send private message

PostPosted: Tue Jun 27, 2006 2:15 am     Reply with quote

future wrote:
In the only datasheet I've found about the sd specs, I couldn't get any information about the correct timing and clock polarity.
The information about the clock is not exhaustive, but in the section on Bus Timing it states
Quote:
Data must always be sampled on the rising edge of the clock.
This leaves it up to you to choose either SPI mode 0 or 3, i.e. the clock polarity in inactive state is not important but in your code the initialization didn't match the polarization of the SPI function.

Do you have the MMC v3.1 specification? This was the last version distributed before the MMCA started asking money for the documentation: http://www.vvm.com/~darkwing/PDF/mmcsys-version_3-1.pdf

Your command() function has two weak points:
1) before sending the command you should check for the card not being busy (the card should return a 0xFF on your first SPI( 0xFF ) call)
2) At the end when returning the response you assume the card gives you the result as the second byte. Often this will be true but you can not rely on it, according to the specifications it can be 1 to 8 bytes delay.

Also double check your hardware, SDO of the PIC is to go to SDI of the MMC/SD card and vice versa.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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