View previous topic :: View next topic |
Author |
Message |
DiegoGarcia
Joined: 01 Mar 2008 Posts: 48
|
How to correct use the mmcsd write and read functions ? |
Posted: Mon Mar 31, 2008 9:16 am |
|
|
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
|
|
Posted: Mon Mar 31, 2008 10:11 am |
|
|
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
|
|
Posted: Mon Mar 31, 2008 10:25 am |
|
|
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
|
|
Posted: Mon Mar 31, 2008 12:35 pm |
|
|
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
|
|
Posted: Mon Mar 31, 2008 1:00 pm |
|
|
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
|
|
Posted: Mon Mar 31, 2008 1:21 pm |
|
|
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
|
|
Posted: Mon Mar 31, 2008 2:31 pm |
|
|
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
|
|
Posted: Mon Mar 31, 2008 4:03 pm |
|
|
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
|
|
Posted: Mon Mar 31, 2008 4:19 pm |
|
|
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
|
|
Posted: Tue Apr 01, 2008 2:24 pm |
|
|
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
|
|
Posted: Tue Apr 01, 2008 5:15 pm |
|
|
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
|
|
Posted: Wed Apr 02, 2008 8:01 am |
|
|
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
|
|
Posted: Wed Apr 02, 2008 9:51 am |
|
|
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
|
|
Posted: Wed Apr 02, 2008 12:07 pm |
|
|
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
|
|
Posted: Thu Apr 03, 2008 12:46 pm |
|
|
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
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 |
|
|
|