This is only a preview of the May 2011 issue of Silicon Chip. You can view 29 of the 104 pages in the full issue, including the advertisments. For full access, purchase the issue for $10.00 or subscribe for access to the latest issues. Items relevant to "The SportSync Audio Delay Module":
Items relevant to "The Maximite Computer, Pt.3":
Items relevant to "12V 100W Converter With Adjustable 15-35V DC Output":
Items relevant to "Phone Line Polarity Checker":
Purchase a printed copy of this issue for $10.00. |
Memory card
compatibility
issues
by Nicholas Vinen
An increasing number of SILICON CHIP projects use memory cards
for storing data, loading software and the like. Originally intended
for digital cameras, mobile phones etc, these cards are small,
now quite inexpensive and can store an enormous amount of data
(8 and 16GB cards are now common). But as some readers have
discovered, there can sometimes be issues . . .
M
any of our projects provide
an interface with a memory
card for data storage. These
include the Music and Speech Recorder (August 2009), the Webserver in a
Box or WIB (November 2009 to January
2010), the DAB+/FM Tuner (October to
December 2010), the Digital Lighting
Controller (October to December 2010)
and the USB Data Logger (December
2010 to February 2011).
The memory cards used with these
projects can be MultiMediaCards
(MMC; up to 16GB), Secure Digital
(SD; up to 4GB) or Secure Digital High
Capacity (SDHC; up to 64GB).
Mode
In each case, we interface with these
devices in “1-bit” mode, which is like
the Serial Peripheral Interface (SPI)
protocol.
It is a 4-wire bus utilising a clock
line (driven by the micro), two lines
for bidirectional serial data transfer
and a chip select line, to activate the
memory card and indicate the start
and end of data packets.
In the later model MMC cards and
for all SD and SDHC cards, there is
also a “4-bit mode” which provides
62 Silicon Chip
faster data access and an expanded
set of commands.
Virtually all computers and most
other devices which require high
speed data transfer (eg, digital still
and video cameras) use this mode. The
1-bit mode is provided primarily for
use with microcontrollers, to reduce
overhead and complexity.
Some readers have reported that
certain memory cards do not work in
these projects.
We have previously released firmware updates for some of these projects to address bugs in the memory
card routines, for example some early
versions did not work with 2GB SD
cards at all.
These cards report information in
a different way to all other SD cards
and the early software versions did not
include a special case to handle them.
All of our current firmware releases
incorporate this fix.
However, some cards were still not
being properly recognised. One reader
kindly sent us the SD card in question
so that we could figure out what was
going on.
Ultimately we tracked the bug down
to what seems to be an error in the
memory card controller itself. We suspect that this is not normally noticed
since it only seems to affect operation
in 1-bit (SPI) mode.
Updated firmware is now available for all the previously mentioned
projects on the SILICON CHIP website.
They contain a work-around which
allows these problematic memory
cards to be used with our projects. The
DAB+/FM Tuner and Digital Lighting
Controller contain software “bootloaders” which allow the firmware to be
updated without any special tools.
For the other projects, a programmer
(such as the PICkit3) will be needed to
install the updated code.
Here is a quick explanation of how
the memory card communication
works, the problems we found and
how we worked around them.
Memory card protocol
To send a command, the microcontroller brings the chip select line low
and then sends 48 bits of data. The
data bits are received by the card on
the positive edge of each clock pulse. A
sample command sequence, for command 17 (block read) is shown in Fig.1.
The first byte (eight bits) contains
siliconchip.com.au
DI
COMMAND
6 bits = 17
(read block)
BLOCK ADDRESS
(32 bits)
CHECKSUM
(7 bits)
STOP BIT (1)
START BITS (2)
EXAMPLE OF MEMORY CARD BLOCK READ COMMAND SEQUENCE
held high
0 1 0 1 0 0 0 1 x x x x . . . x x x x c c c c c c c 0
RESPONSE
(8 bits* )
DATA READY
(0xFE)
DATA
(512 x 8 bits)
DATA RESPONSE
(8 bits)
CRC
(16 bits)
0 e e e e e e e 1 1 1 1 1 1 1 0 d d d d . . . d d d d e e e 0 e e e 1 c c c . . . .c c c
DO
CS
ADDED CODE: ON ERROR, RETRY UP TO THREE TIMES
* response length depends on command
Fig.1: an example memory card command sequence for a single block (512 byte) data read operation. Data is sent from
the microcontroller to the memory card on the DI line and vice versa on the DO line.
two start bits and then the command
number (0-63).
Following this is four bytes (32
bits) of data, which for a block read
command contains the address of the
data block to be read. This is followed
by a seven bit checksum and finally
a stop bit.
The checksum allows the card to
detect command transmission.
After a command is sent, the microcontroller reads back one or more
bytes; how many depends on which
command was sent.
For a block read, the result is a single
byte and this indicates whether there
is an error. A response of all zeroes
indicates that the command is successful and that data will follow.
The microcontroller then continually reads eight bits from the card,
waiting for the data transmission to
be ready. This allows the card to move
data into buffers as necessary.
For write commands, the delay is
usually longer as it takes time to erase
and prepare the FLASH memory for
writing.
Once the card is ready, it transmits
a “token” bit sequence (in this case,
0xfe).
When that token is received, the
micro can read the 512 bytes of data
from the block requested. The data is
followed by another status response
and a 16-bit data checksum. The card
is then ready for another command.
One complication with the read/
write procedure has to do with addressing. SDHC cards use block addressing, so address 0 indicates the
first 512 bytes, address 1 the next 512
bytes, etc.
MMC and SD cards use byte addressing so to read the second set of
512 bytes, the address to be passed is
512, rather than 1.
siliconchip.com.au
Problematic controller
So what is it that goes wrong with
this process with the troublesome SD
cards?
Actually, the first read operation
completes successfully and the checksum is correct. The data returned is all
valid. The first block read we perform
in our software involves reading the
first blocks on the card (block 0) which
contains the partition table.
Once the partition table has been
read, we then need to read the first
block of the first partition to check
what file system it is using.
On some cards, this second block
read fail. The 8-bit response we receive
immediately after the command is
00111111.
This is a nonsense error code which
would seem to indicate that the card is
in “idle state” and “erase reset” state
simultaneously and that four errors
have also occurred: illegal command,
CRC error, erase sequence error and
address error (see Fig.2).
It is hard to see how it is possible to
have an “erase sequence error” when
we are not writing to the card.
Adding a delay between the first and
second block read doesn’t make this
BLOCK READ RESPONSE FORMAT
0
0
1
1
1
1
1
1
Parameter error
Address error
Erase sequence error
C ommunications C RC error
Illegal command
Erase reset
In idle state
Fig.2: the meaning of each bit for
the 8-bit response to a block read
command, showing the problematic
error state.
error go away, so it does not seem to
be due to the memory card being busy.
The solution to this strange situation
is straightforward: when we get an error after a read command (even if it’s
a nonsensical one), we immediately
repeat the same command again.
Our test card always succeeds when
we attempt the read a second time.
Rather than looking for this specific
error condition we simply retry each
command up to three times if it fails
for any reason.
That should also cover situations
where a communication glitch (eg, due
to noise) causes occasional command
failures. After making this change, the
problem card worked reliably.
Other controller bugs
There is one additional wrinkle.
Before we could discover and fix the
problem described above, we had to
fix another problem that is also specific
to this particular model of card (or
controller). This only occurred with
the DAB+/FM Tuner firmware.
Since the tuner does not have a connection to the switch in the card socket
which indicates whether a memory
card is present, it periodically sends
a command to the card to check that
it is still there.
The command selected has no side
effects; its sole purpose is to establish
that the card is still there and communicating normally.
Originally the command used was
CMD9, which reads the Card-Specific
Data (CSD) register. This contains
information on the format and capabilities of the memory card. This command is normally used during memory
card initialisation but it should be
possible to send it again later.
In this case, the command sent during initialisation is successful but if
May 2011 63
it is sent again later, the memory card
locks up completely and no longer
responds properly to any command.
This includes the reset command, so
it is necessary to remove power to the
memory card to get it working again.
The fix for this problem is simply
to use CMD13 to check for card presence instead of CMD9. CMD13 reads
the card status register instead and
this does not cause the same problem.
We have yet to find out why sending
CMD9 should cause the card to lock
up but we assume that it’s the result
of the same faulty controller logic that
causes the problem with block reads.
The fact that this particular SD card
exhibits two mystifying errors which
other cards typically do not suggests
strongly that the problem is in the card,
rather than our software.
Installing the new firmware provided for each of these projects will allow
the use of these problematic cards.
We have had several readers report
that the changes were successful in
allowing the use of a memory card
which previously did not work, suggesting that the controller problem is
not especially rare.
SC
USB Data Logger firmware improvements
We recently made some improvements to the firmware for the USB
Data Logger (December 2010 to February 2011) in addition to the memory
card related fixes. These were alluded
to in the errata published last month
but here are some additional details.
Firstly, while tracking down a power
supply problem, we noticed that when
power was initially applied to the
data logger (eg, when the battery is
inserted), it often went into the USB
bootloader mode even though pushbutton S2 was not being held down at
the time. This was especially the case
when the battery voltage was on the
low side but sometimes happened
even with higher battery voltages.
The reason for this is that the state
of pushbutton S2 was being sensed
using a digital input pin and S2 is multiplexed with the battery voltage sensing resistors. When S2 is pressed, pin
AN4 of IC1 is pulled to ground and
so if used as a digital input (RA5), it
registers as low (zero). But when S2 is
not pressed, it will only be pulled up to
a maximum of half the battery voltage.
If the battery is 3V then this is 1.5V.
But the datasheet says that for digital input pins with a TTL buffer (which
includes RA5/AN4) and a 3.3V micro
supply voltage, the minimum voltage
to reliably read a pin as high is 1.625V.
This is unlikely to be exceeded with
any two cell AA battery. So the firmware would often read the state of S2
as being pressed even when it was
not.
To solve this, we changed the code
to instead use the ADC to measure
the voltage at pin AN4 when power
is first applied, after a short delay, to
allow the voltages to stabilise. It now
only considers S2 to be pressed when
the resulting voltage reading is very
close to zero and this results in much
more reliable detection of the state of
64 Silicon Chip
S2. As a result, it no longer goes into
bootloader mode when it should not.
Initial clock source
We also made some changes to the
initial clock source for the micro. This
is related to the power supply and it
reduces the current drawn at start-up
and with a low battery voltage.
Because the micro is driven from a
boost regulator that runs off the battery, as the battery voltage drops the
current drawn from it increases. If the
voltage is low enough then the ratio of
battery current to micro supply current
can become quite high and so even
quite modest supply current drawn by
the micro in this condition can present
a significant load to the battery.
This compounds the problem because internal resistance in the battery
will make its voltage drop even further
under heavy load. Because the firmware
puts the micro to sleep when the battery
voltage is low, it might seem like this is
not an issue but it is for two reasons.
Firstly, when the battery voltage drops
low enough, the micro voltage also
drops and this causes it to reset. When
it is reset it is no longer in sleep mode
but if the voltage is low enough, it can
not start up properly and so will not go
back to sleep. It gets stuck in “limbo”
and this can cause excessive current
drain from the battery which will flatten
it completely.
Secondly, the micro does not go into
sleep mode immediately if the battery
voltage is low. First it must go through
the start-up procedure and spend some
time sampling the battery voltage before
it decides to go to sleep. So even if the
micro does manage to start back up after
a reset when the battery is low, it can
still draw a lot of current initially.
Ideally, we would make the microcontroller start up using a low speed, low
power oscillator such as the internal
RC oscillator and then switch over to
the crystal for high speed operation
once it has confirmed that the battery
voltage is sufficient. Unfortunately the
PIC18F47J53 family does not support
dynamic switching from the RC oscillator to a crystal (it can do the opposite
though).
The best we could do is have the
micro start up using the crystal but then
immediately switch to low speed, low
power operation and check the battery
voltage. It waits in this state for the battery voltage to be high enough before
it goes into high speed mode and goes
through the full initialisation process.
Our testing shows that this approach
goes a long way towards reducing current drawn from the battery at start-up,
especially when battery voltage is low.
It also effectively prevents the micro
from getting stuck in “limbo”.
Due to the way the boost regulator
operates, current drain is still higher
with a low battery voltage but in combination with the inductor change specified in the errata last month, it will not
run the battery down as quickly as it
did with the original firmware.
Low battery sleep mode
We made one more change to the
USB Data Logger firmware and this
has to do with how it checks the battery
voltage. The original firmware would
only decide to sleep if the battery voltage was low as long as a memory card
was inserted and at least one script
was running. While this would normally
be the case, we decided that it should
check the battery voltage regardless.
So we added an extra check in the
main loop which will put the micro to
sleep if the battery voltage is below
the specified threshold, regardless of
what the Data Logger is doing. This
provides an extra layer of battery discharge protection.
SC
siliconchip.com.au
|