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

How to correct use the mmcsd write and read functions ?

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



Joined: 01 Mar 2008
Posts: 48

View user's profile Send private message

How to correct use the mmcsd write and read functions ?
PostPosted: Mon Mar 31, 2008 9:16 am     Reply with quote

Hi guys its me again ;)
I've tryed to write to a sd card using the follow code

Code:
const char sCard[118] = "%B0000000000000000¨TEST CARD                   ¨0000000000000000000000000000000:ç0000000000000000=00000000000000000000:";
                  for (i=0; i<117;i++)
                   {
                     value = sCard[i];
                   
                     out_data[0] = 0x12;
                     out_data[1] = 0x00;
                     out_data[2] = value;

                     //Write character to the sd card
                     rWrite = mmcsd_write_byte(address, value);
                     mmcsd_flush_buffer();

                     if (rWrite)
                     out_data[3] = 0x01; else
                     out_data[3] = 0x00;

                     usb_put_packet(1, out_data, 4, USB_DTS_TOGGLE);
                     address++;
                  }


So when I try to read the data from de card using the code :
Code:

                  for (i=0; i<117;i++)
                   {
                    out_data[0] = 0x22;
                    out_data[1] = 0x00;
                   
                    //Read the data from sd card
                    rRead = mmcsd_read_byte(address, &value);
             
                    out_data[2] = value;

                    if (rRead)
                       out_data[3] = 0x01; else
                       out_data[3] = 0x00;                 

                    usb_put_packet(1, out_data, 4, USB_DTS_TOGGLE);
                    address++;

                    delay_ms(50);                   
                   }

The problem is that the value always returns 0x00 ... dont know why.
I've tryed to use the mmcsd_write_data function but I dont know how it works ... can you guys give me a light ???

Thanks and Regards,
Diego Garcia
ckielstra



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

View user's profile Send private message

PostPosted: Mon Mar 31, 2008 10:11 am     Reply with quote

mmcsd_write_byte() returns the result of the write operation. In your case this will always be OK because mmcsd_write_byte() writes to a buffer which is only flushed at crossing a 512 byte boundary and this never occurs because you call the flush function after every byte you write to the buffer.

What is the result of the mmcsd_flush_buffer() call? My guess is you will see an error code here.
DiegoGarcia



Joined: 01 Mar 2008
Posts: 48

View user's profile Send private message

PostPosted: Mon Mar 31, 2008 10:25 am     Reply with quote

Its returning 0, so it indicates the operation was done without problem ...

But I dont know why the read operation is reading 0.

Thanks for your reply ckielstra.
Regards,
Diego Garcia
ckielstra



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

View user's profile Send private message

PostPosted: Mon Mar 31, 2008 12:35 pm     Reply with quote

Sorry, but your code looks fine to me and with the small code fragments you provided I can't give you more help. The declaration of several variables is missing and we can't see if you are reading and writing with the same value in the address variable.
Please post a small (max. 1 page) and complete test program, that means including #fuses statements etc. so we can copy/paste it in our compiler.

Just another mark on your write routine. CCS is providing a buffered write function for a reason: an MMC / SD card is programmed and erased in blocks of 512 bytes. So in order to modify a single byte the whole block has to be read into RAM, the single byte is modified, the block in the card is erased and then written with the new contents. FLASH memory has it limitations and you can only do the erase/write for several thousand times on a block. Because you are calling the flush function after every single byte write your card will be damaged soon. Instead, move the flush function outside the loop.
DiegoGarcia



Joined: 01 Mar 2008
Posts: 48

View user's profile Send private message

PostPosted: Mon Mar 31, 2008 1:00 pm     Reply with quote

O sorry for that ;)

Here is my complete code I've done the changes that you sayd will test it after post it to you.

Code:
#include <18F67J50.h>

#fuses H4_SW
#fuses PLL5   
#fuses NOCPUDIV
#fuses NOWDT   
#fuses NOIESO
#fuses NOXINST
#fuses NOSTVREN
#fuses NOFCMEN 
#fuses NOPROTECT
#fuses NODEBUG

// 48Mhz clock
#use delay(clock=48000000)

#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)
#use fast_io(f)

#byte portA = 0xF80
#byte portB = 0xF81
#byte portC = 0xF82
#byte portD = 0xF83
#byte portE = 0xF84
#byte portF = 0xF85

#bit Led = portf.2

#DEFINE USB_HID_DEVICE  TRUE

#define USB_EP1_TX_ENABLE  USB_ENABLE_INTERRUPT   
#define USB_EP1_TX_SIZE    64 

#define USB_EP1_RX_ENABLE  USB_ENABLE_INTERRUPT
#define USB_EP1_RX_SIZE    64 

#define USB_CON_SENSE_PIN PIN_D7

#include <pic18_usb.h>     
#include <usb_desc_new.h>
#include <usb.c>


#use rs232(baud=9600, UART1, errors)


#define MMCSD_PIN_SCL     PIN_C3 //o
#define MMCSD_PIN_SDI     PIN_C4 //i
#define MMCSD_PIN_SDO     PIN_C5 //o
#define MMCSD_PIN_SELECT  PIN_C2 //o

#include <mmcsd.c>

//Used to enable usb module
#bit PLLEN = 0xf9b.6
                              
const char sCartao[118] = "%B12345670123456¨TEST CARD                 ¨1234567890123456789012345678901:ç01234567890123456=012345678901234567890:";

void main()
{
   int i,rRead,rWrite;
   int8 out_data[4];
   int8 in_data[2];
   int32 address;
   BYTE value;

   //Enable the PPLEN bit or the usb will not work
   PLLEN = 1; 
   
   set_tris_e(0b00011111);
   set_tris_f(0b00000000);
   
   porte = 0x00;
   portf = 0x00;   

   Led = 1;
   
   if (mmcsd_init())
   {     
      while(TRUE);
   }
   
   usb_init_cs();

   while (TRUE)
    {
     
     usb_task();         
     
      if (usb_enumerated())
       {               
            if (usb_kbhit(1))
             {
             
              usb_get_packet(1, in_data, 2);             
           
              if (in_data[0] == 0x01)  //Read data from SD Card and sends to USB
                 {
                 
                  for (i=0; i<117;i++)
                   {
                    out_data[0] = 0x22;
                    out_data[1] = 0x00;
                   
                   
                    rRead = mmcsd_read_byte(address, &value);
                     
                    out_data[2] = value;
                   
                    out_data[3] = rRead;

                    usb_put_packet(1, out_data, 4, USB_DTS_TOGGLE);
                   
                    address++;         

                    delay_ms(50);                   
                   }                 
                 }

              if (in_data[0] == 0x02)  // Writes data to the SD Card and sends to USB
                 {
                  for (i=0; i<117;i++)
                   {
                     value = sCartao[i];
                   
                     out_data[0] = 0x12;
                     out_data[1] = 0x00;
                     out_data[2] = value;
                   
                     rWrite = mmcsd_write_byte(address, value);
                     
                     out_data[3] = rWrite;

                     usb_put_packet(1, out_data, 4, USB_DTS_TOGGLE);
                     address++;
               
                     delay_ms(50);
                   } //End For
                   //Sends the data to the card
                   mmcsd_flush_buffer();
                 } //End if

             } //End usb kbhit         
         delay_ms(10);
       } //End usb enumerated   
    } //End While True
}//End void Main


Thanks a lot for you help ckielstra I will try to test it now, any good results I will post it here again ;)

Regards,
Diego Garcia
DiegoGarcia



Joined: 01 Mar 2008
Posts: 48

View user's profile Send private message

PostPosted: Mon Mar 31, 2008 1:21 pm     Reply with quote

Here is the complete log from PC:

Sends the write command from pc to pic

W 00 02 00 00 00

Where W is the Operation
00 is the report number
02 is the action aka in_data[0]
00 is the second in_data[1]
00 is the second in_data[2]
00 is the second in_data[3]

Pic response:

R 00 12 00 25 00
R 00 12 00 42 00
R 00 12 00 31 00
R 00 12 00 32 00
...

So the response is rigth for write action, but for read action the response is always:

R 00 22 00 00 00
...

Regards,
Diego Garcia


Last edited by DiegoGarcia on Wed Apr 02, 2008 8:43 am; edited 1 time in total
DiegoGarcia



Joined: 01 Mar 2008
Posts: 48

View user's profile Send private message

PostPosted: Mon Mar 31, 2008 2:31 pm     Reply with quote

Ok I've inserted the address 0x05 before the for in the read and in the write action. Now when I write it works and when I read works to but if I power off my circuit then power on again and try to read again it brings me the R 00 22 00 00 00 response ... so I think the data is not been saved ... or an I missing something ?

Thanks a lot,
Regards,
Diego Garcia
ckielstra



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

View user's profile Send private message

PostPosted: Mon Mar 31, 2008 4:03 pm     Reply with quote

The flush_buffer function is the code that really writes to the card. Can you add similar code to show the return value of this function? And what is the returned value?
DiegoGarcia



Joined: 01 Mar 2008
Posts: 48

View user's profile Send private message

PostPosted: Mon Mar 31, 2008 4:19 pm     Reply with quote

Ok I've added the code and the return value was 0x80 = RESP_TIMEOUT.

So what can I do ?

thanks for the great help ;)
Regards,
Diego Garcia
DiegoGarcia



Joined: 01 Mar 2008
Posts: 48

View user's profile Send private message

PostPosted: Tue Apr 01, 2008 2:24 pm     Reply with quote

Ok I found where the problem was !
It was an hardware problem ! The connections from sd card to my pic was done with an resistor, and in my especific case it wasnt necessary because my pic already works with 3.3v so it was driving the card to 2v !

Now I just want to know why after write I cannot read it, I have to reboot my circuit to acomplish that !

Thanks a lot guys
Regards,
Diego Garcia
DiegoGarcia



Joined: 01 Mar 2008
Posts: 48

View user's profile Send private message

PostPosted: Tue Apr 01, 2008 5:15 pm     Reply with quote

I was thinking that solves the problem but now I'm confused ...
It seens that my sd cards wasnt connected at the board and the sd functions was saving the data to some place, but i dont know where ...

Its very strange ...
If I insert my sd card into the sd connector the result of the read operation is always 00, and the value read is 00, the result of my write operation is 0x80 ... but if I remove the sd card from the connector, then write and it writes to some place that I dont know where but it remains so If i reset the hole circuit and read without the sd the data is readed correct ... what is happening here ??

Someone already saw this strange behavior ?

Thanks guys,
regards,
Diego Garcia
DiegoGarcia



Joined: 01 Mar 2008
Posts: 48

View user's profile Send private message

PostPosted: Wed Apr 02, 2008 8:01 am     Reply with quote

Hi guys its me again ;)

I've some doubts about the sd connection and operation, should my sd card be formated with some type of format or doesnt matter ? My hardware connection is direct from sd connector to the pic because my circuit is using 3.3v so is this the right way to do it ?

here is the link to my spi sd card connection http://www.unitone.com.br/arquivos/esqspi01.jpg

Thanks guys,
Regards,
Diego Garcia
ckielstra



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

View user's profile Send private message

PostPosted: Wed Apr 02, 2008 9:51 am     Reply with quote

In your schematic SCK is also connected to ground. This is a major problem and could damage the output of your PIC. Never connect I/O pins directly to ground or the power supply but always insert a resistor to limit the current.
Same applies to the Din line and CS.

Check the MMC or SD specifications: the CMD and DAT lines require pull up resistors because in the start-up phase the drivers use Open Collector instead of push-pull. Add a 100k pull up to both the data lines (Din and Dout). Don't add a pull-up to the clock line.
Not required but good design is to add a 100k pull up to the CS line as well.

Add a 100nF capacitor between Vss1 and Vdd as close as possible to the card connector.
DiegoGarcia



Joined: 01 Mar 2008
Posts: 48

View user's profile Send private message

PostPosted: Wed Apr 02, 2008 12:07 pm     Reply with quote

Ok thanks ckielstra I will try to do what you had sayed.

I will post the results here,

Regards,
Diego Garcia
DiegoGarcia



Joined: 01 Mar 2008
Posts: 48

View user's profile Send private message

PostPosted: Thu Apr 03, 2008 12:46 pm     Reply with quote

Ok now its working ;)
but it wasnt a connection problem ...
I 've found that the fast_io definition was not let the functions output_drive and output_float work correctly.
So I change for now to the standard_io and everything works nice Smile

I hope it helps someone in the forum ;)

The compiler version that I'm using is 4.057 and I try with the 4.065 ...
I think it is a compiler bug but any way ..

Thanks for your big help ckielstra ;)
Regards,
Diego Garcia
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