View previous topic :: View next topic |
Author |
Message |
Marco27293
Joined: 09 May 2020 Posts: 126
|
PIC18F47J53 CCS C Compiler 5.090 mmcsd_write_block issue |
Posted: Fri Mar 08, 2024 5:47 am |
|
|
Hi,
regarding microsd (SDHC 32GB) write block function from mmcsd_m.c library (https://www.ccsinfo.com/forum/viewtopic.php?p=214008)
Code: |
MMCSD_err mmcsd_write_block(uint32_t address, uint16_t size, uint8_t* ptr)
{
MMCSD_err ec;
uint16_t i;
// send command
mmcsd_select();
ec = mmcsd_write_single_block(address);
if(ec != MMCSD_GOODEC)
{
mmcsd_deselect();
return ec;
}
// send a data start token
MMCSD_SPI_XFER(DATA_START_TOKEN);
// send all the data
for(i = 0; i < size; i += 1)
{
MMCSD_SPI_XFER(ptr[i]);
}
// if the CRC is enabled we have to calculate it, otherwise just send an 0xFFFF
/* if(g_CRC_enabled) // already FALSE
MMCSD_SPI_XFER(mmcsd_crc16(ptr, size));
else
{ */
MMCSD_SPI_XFER(0xFF);
MMCSD_SPI_XFER(0xFF);
// }
// get the error code back from the card; "data accepted" is 0bXXX00101
ec = mmcsd_get_r1();
if(ec & 0x0A)
{
mmcsd_deselect();
return ec;
}
// wait for the line to go back high, this indicates that the write is complete
while(MMCSD_SPI_XFER(0xFF) == 0);
mmcsd_deselect();
return MMCSD_GOODEC;
}
|
I'm facing a weird and serious problem.
Sometimes (not so often actually) microsd data have been corrupted (all bytes equal to 0xFF).
Reading SD specifications (https://www.taterli.com/wp-content/uploads/2017/05/Physical-Layer-Simplified-SpecificationV6.0.pdf), I found:
Code: |
While the card is busy, resetting the CS signal will not terminate the programming process. The card will
release the DataOut line (tri-state) and continue with programming. If the card is reselected before the
programming is finished, the DataOut line will be forced back to low and all commands will be rejected.
Resetting a card (using CMD0 for SD memory card) will terminate any pending or active programming
operation. This may destroy the data formats on the card. It is in the responsibility of the host to prevent
this for occurring.
|
Moreover I noted that in the above function I have:
Code: |
while(MMCSD_SPI_XFER(0xFF) == 0);
mmcsd_deselect();
|
Could the problem be located here ?
Implementing a timeout like:
Code: |
// After Master has sent the block data
// Wait microsd "NOT busy" status
timeout = TIMEOUT_VALUE;
do {
response = MMCSD_SPI_XFER(0xFF);
if(--timeout == 0) {
mmcsd_deselect();
return TIMEOUT_ERROR;
}
} while(response != 0xFF);
mmcsd_deselect(); // Deselect microsd
|
Could it fix my problem ?
I need help in order to:
1) Identify a reasonable problem cause
2) Fix it
Reagrds,
Marco |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Fri Mar 08, 2024 7:41 am |
|
|
What you quote from the spec is saying that once a write it started, it
will continue even if the CS line is released. Why do you think this has
anything to do with your all 0xFF's???
The commonest cause for cards getting corrupted during a write is not
having adequate smoothing on the supply. SD cards draw very significant
pulses of power during the actual write operation. Amazingly high levels
on some cards. nSec pulses of up to 0.8A!... Now because these are so
short and quick, they have to be supplied by reservoir capacitors
immediately adjacent to the card. A PSU does not respond quickly
enough.
Even though the general consumption may only be perhaps 80mA when
writing, it is the switching transients that cause problems.
There needs to be a pair of decoupling capacitors as close as possible to
the card supply connections, working on the old principle of 'large then small'. so the bigger one closest to the card, then the smaller one.
47yF low ESR, the a 0.1uF ceramic or polyester.
Basically if the card supply droops during the write, the cells retain their
erased (0xFF) state.
Get your hardware right, and the problems will pretty certainly vanish.... |
|
|
Marco27293
Joined: 09 May 2020 Posts: 126
|
|
Posted: Fri Mar 08, 2024 7:55 am |
|
|
I have on supply, very close (few millimeters) to microsd pins:
Tantalium 680uF cap
Ceramic 22uF cap
Ceramic 100nF cap
So I think the problem is somewhere else...
Please could you check the while loop sending 0xFF, is it ok ?
Regards |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Fri Mar 08, 2024 7:55 am |
|
|
Ckeck your hardware again.
Check the pull-up resistor on the DO line from the card. I had an issue once where the pull up (an SMD resistor) was perfectly soldered but was open circuit. The pull-up is a crital component as the card's DO line is in open drain mode unit the controller has been initialized. Without the pull-up you can't be sure the status returned during initialization is valid
Check the soldering of the connector. If you ar using a 5v PIC, check you level conversion logic.
If this is your own custom PCB, yuo may have issues if the SPI bus lines are too long. Try testing with a slower SPI bus speed (say 2MHz)
Personally I don't like your loop code. If your logic was correct, and the card was busy, your loop is bombarding a busy card with these transfers. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
Marco27293
Joined: 09 May 2020 Posts: 126
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9232 Location: Greensville,Ontario
|
|
Posted: Fri Mar 08, 2024 8:27 am |
|
|
curious...1st thing I checked was the PIC datasheet....it's 3 volts.
so not a logic level problem.
agree correct caps and resistors is real important. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Fri Mar 08, 2024 11:25 am |
|
|
If you are enabling the SD card using a MOSFET switch, several comments
apply:
First you need to allow sufficient time after enabling the switch for the
capacitors to fully charger. You need capacitors after the switch as well
as before.
You need to re-initialise after turning the power on. Includes switching
the SPI back down to slow speed, and sending the full init sequence.
Then you muct not switch this off untill the write has completed. You need
to physically read the data output line from the card, and only disconnect
the supply after this goes high.
I suspect you are turning the power off before the write actually
completes.
Then the question is 'why'?. If you put an SD properly to sleep it's
power consumption goes to almost zero. A card like the Sandisk 256MB
draws under 0.05mA when asleep. |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Fri Mar 08, 2024 7:21 pm |
|
|
I agree with Ttelmah, adding power control for the SD card which, when. idle, draws a similar current as the switch does. So virtually no power saving but the switch has added complexity to your software and handling of the power control logic.
Interestingly, you could have achieved a similar outcome for power management by using the same LDO instead of the switch and then using the enable PIN of the LDO to turn on and off the SD card. The idle current would have been about the same as using the switch but now you don't need two different component sources. But I would not do this either, instead I would just power the SD card from the output of the existing LDO.
Regarding if the LDO is ok for the solution, without seeing the rest of the circuit, I could not guess how much power you need normally for your design however, as already pointed out, the SD card's current consumption is low until the write cycle where is will draw a lot of current for a very short time. This is usually not an issue provided you have a low ESR capacitor (say a tantalum or ceramic) as close to the SD card socket as practical as you have done in your implementation. This capacitor will deliver the peak current required for the write operation.
Bottom line.. get rid of the power switch for the SD card _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
|