|
|
View previous topic :: View next topic |
Author |
Message |
future
Joined: 14 May 2004 Posts: 330
|
First try at MMC/SD, seeking for help |
Posted: Mon Jun 26, 2006 10:40 am |
|
|
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
|
|
Posted: Mon Jun 26, 2006 12:54 pm |
|
|
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
|
|
Posted: Mon Jun 26, 2006 5:48 pm |
|
|
I know there are many mistakes, but I am trying
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
|
|
Posted: Tue Jun 27, 2006 2:15 am |
|
|
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. |
|
|
|
|
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
|