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

SD card problems

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



Joined: 24 Jun 2005
Posts: 206

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

SD card problems
PostPosted: Fri Feb 08, 2008 10:36 pm     Reply with quote

Hi All, I am trying to use a SD card for mass storage. I have spent all day reading the posts here, and the Sandisk datasheet, but still don't understand why this code is not working. I am using a PIC18F4550 running at 5v, so I also have the 3k3 - 1k8 resistor divider set up. SD card is been powered by 3.3v regulator. I have the Din and Dout lines pulled up with 100k resistors. When I run the code, I never get past the CMD0. I always get 0 from the card. If I take the card out, I get 255, so I think the hardware is OK.

My code is as follows

Code:

#include <18F4550.h>

#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOBROWNOUT
#use delay(clock=48000000)

#include "lcd420.c"

#byte SSPBUF = 0xFC9
#byte SSPCON = 0xFC6
#byte SSPSTAT = 0xFC7
#bit  BF = SSPSTAT.0
#bit SMP = SSPSTAT.7
#bit CKE = SSPSTAT.6
#bit CKP = SSPCON.4
#bit SSPM1 = SSPCON.1
#bit SSPEN = SSPCON.5

#define SD_CS PIN_A1

int SD_INIT()
   {
      int i;

      setup_spi(SPI_MASTER|SPI_XMIT_L_TO_H|SPI_L_TO_H|SPI_CLK_DIV_16);
 
      output_high(SD_CS);

      for(i=0; i < 80; i++)         //start and reset
         {
            spi_write(0xFF);
         }

      output_low(SD_CS);
      
      delay_ms(5);

//      spi_write(0xff);
      spi_write(0x40);
      spi_write(0x00);
      spi_write(0x00);
      spi_write(0x00);
      spi_write(0x00);
      spi_write(0x95);
      
      return spi_read(0xFF);
      
   }


void main()
   {
      lcd_init();
      printf(lcd_putc,"Ready");

      while(SD_INIT() != 1)
         {
            lcd_gotoxy(1,2);
            printf(lcd_putc,"ERROR");
            delay_ms(500);
         }
   
      while(1)
         {
            lcd_gotoxy(1,3);
            printf(lcd_putc,"ok");   
         }
   }


I have tried to setup the SSP with the following, but it does not help.

Code:

// Init SPI
SMP=0;       
CKE=0;       
CKP=1;       
SSPM1=1;           
SSPEN=1; 


I am guessing it has something to do with the way I setup the SPI ports. I would like to use USB in this project, so I am running the PIC at 48Mhz. I am not too sure how I am meant to use SPI_CLK_DIV. I have tried a range of values, like SPI_CLK_DIV_16, SPI_CLK_DIV_32 and SPI_CLK_DIV_64, but it does not seem to work.

Can anyone see any other problems?

Thanks, Mark
Pret



Joined: 18 Jul 2006
Posts: 92
Location: Iasi, Romania

View user's profile Send private message

PostPosted: Sat Feb 09, 2008 5:40 am     Reply with quote

As far as i know... Select means output_low and deselect output_high. You should reverse that. One other thing, each time you wish to send something(cmd or data) you should call select first. In your code, CMD0 is ignored...
ckielstra



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

View user's profile Send private message

PostPosted: Sat Feb 09, 2008 8:05 am     Reply with quote

The largest problem in SD_INIT() is that after sending CMD0 you expect the card to send a response in the next few microseconds. According to the specs you should instead send 0xFF in a loop until you receive a value <> 0xFF or timeout.

Another smaller problem is your SPI clock frequency. It is specified that at startup the maximum clock frequency is maximum 400kHz. After startup (CMD0) the frequency can be increased to the SD-card's maximum. You are using a constant 48/16 = 3MHz. Depending on brand and age of your card this might work but there are no guarantees. Best is to slow down your clock during init and when successful go full speed.

Before you exit SD_INIT() add code to deselect the SD card.

Before sending a command to the SD card it is a nice addition to check the card to be ready, i.e. send 0xFF and check the response. Repeat until you receive a 0xFF or time out.

But then... why not use one of the MMC card libraries that are already present in the code section of this forum? Even CCS provides an MMC library in the Drivers directory of your compiler. After all, SD cards using SPI are backwards compatible to MMC.
Markdem



Joined: 24 Jun 2005
Posts: 206

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

PostPosted: Sun Feb 10, 2008 12:02 am     Reply with quote

Hi ckielstra, Thank you very much for your help. I have tried to do what you suggested, but the problem still exists. I have now also slowed the pic down to 20MHz, so the spi should be working a 20/64= 312KHz, which is far below 400KHz.

When I run the code below, I get 255 as r1 when i dont have the SD card connected, then I get 0 when I connect it. Do you think that mayby I have some hardware problems? I have orded some PIC18LF's to check without having the resistor dividers, but the problem it, I need to run at 5v as i need to use USB and a LCD.

I am going to use the CCS drivers. I am only writing this code to debug why I can start the card.

Code:

#include <18F4550.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG,VREGEN,NOBROWNOUT
//#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOBROWNOUT
#use delay(clock=20000000)

#include "lcd420.c"

#define SD_CS PIN_A1

int data[514];
int r1;

void SD_INIT()
   {
      int i;
 
      do
         {
            output_high(SD_CS);

            delay_ms(20);

            for(i=0; i < 20; i++)      
               {
                  spi_write(0xFF);
               }
      
            output_low(SD_CS);
      
            delay_ms(20);

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

            do
               {
                  r1 = spi_read(0xFF);
                  lcd_gotoxy(1,1);
                  printf(lcd_putc,"r1=%u",r1);
                  if (r1==1)  break;
               } while(r1 != 1);

         }   while(r1 != 1);   

      lcd_gotoxy(1,2);
      printf(lcd_putc,"Reset OK");

      output_high(SD_CS);
   }


void main()
   {
      setup_spi(SPI_MASTER|SPI_XMIT_L_TO_H|SPI_L_TO_H|SPI_CLK_DIV_64);

      lcd_init();
//      printf(lcd_putc,"Ready");
      SD_INIT();

      while(1)
         {
            delay_ms(1);         
         }
   }


One other thing I have found, is that some examples send 0x00 to reset the card instead of 0x40 as in the sandisk datasheet. I tried this, but it did not help. When I try this in proteous, It looks like the 0x00 command is invalid. The sd card always returns 255.
I have ran out of ideas for this one. I guess I will need to buy another brand of SD card, and see how I go. Is there anything else that you think I could try??

Thanks, Mark
ckielstra



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

View user's profile Send private message

PostPosted: Sun Feb 10, 2008 9:36 pm     Reply with quote

Quote:
When I run the code below, I get 255 as r1 when i dont have the SD card connected, then I get 0 when I connect it. Do you think that mayby I have some hardware problems? I have orded some PIC18LF's to check without having the resistor dividers, but the problem it, I need to run at 5v as i need to use USB and a LCD.
The SPI data input port SDA on pin B0 is of the Schmitt Trigger type. According to Table 28.3 of the PIC18F4550 datasheet these require a logic low of:
0.2Vdd = 0.2 * 5V = 1.0V
and a logic high of:
0.8Vdd = 0.8 * 5V = 4.0V

Running the MMC card at 3.3V you are not meeting the Voltage High level requirements...

You have the following options:
1) Use a PIC18LF processor at 3.3V
2) Add a level converter (either a cheap ic or a resistor / transistor solution).
3) Move away from the hardware SPI unit and use a software based SPI implementation on a TTL level input pin (triggers high level at 2.0V). Surprise, pin B0 when configured as digital input, is TTL level, so you can try this without modifying your current hardware.

Note: an example of a software SPI implementation for an MMC/SD card is mmc_spi.c in the CCS Drivers directory.
andreluizeng



Joined: 04 Apr 2006
Posts: 117
Location: Brasil

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

PostPosted: Fri Mar 07, 2008 8:12 am     Reply with quote

had anybody used a 4gb sd card with fat32 ?
_________________
Andre
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Fri Mar 07, 2008 9:48 am     Reply with quote

I have tested the 4G cards with my own file system. You need to change the initialization sequence to use these cards.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
andreluizeng



Joined: 04 Apr 2006
Posts: 117
Location: Brasil

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

PostPosted: Fri Mar 07, 2008 12:20 pm     Reply with quote

can you tell me the sequence ?

thanks in advance.
_________________
Andre
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Fri Mar 07, 2008 12:46 pm     Reply with quote

Sorry but no, I sell my software. I did give you a hint where changes need to be made.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
andreluizeng



Joined: 04 Apr 2006
Posts: 117
Location: Brasil

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

PostPosted: Fri Mar 07, 2008 12:55 pm     Reply with quote

asmallri,

that hint i already knew, because im constantly debuggin my software. so... i dont think that you gonna lost sells telling me the sequence.

but, anyway.... thanks.
_________________
Andre
Franck26



Joined: 29 Dec 2007
Posts: 122
Location: Ireland

View user's profile Send private message

PostPosted: Sun Mar 09, 2008 3:57 pm     Reply with quote

Hi Markdem,
About the hardware, I have already noticed a lot of problem when you want to change the SPI voltage level by using resistors.
If you look the signal with an oscilloscope, you will see that there is a lot of distortion...
It's why it is always better to use a level translator on chip.
Good luck,
Franck.
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