📜 ⬆️ ⬇️

Full featured SDHC memory card driver for Stm32f4 (part 1)

What is this article for?


All embeds, sooner or later, face the problem of the lack of a microcontroller's ROM for their projects. Well, trite, you need to develop a control system for a simple CNC machine, where the control program is stored on the device itself or a data acquisition system, say, from sensors from some experiment - it is obvious that the microcontroller was not originally intended to store such arrays of information.

There are a lot of solutions of this case, ranging from the acquisition and connection of EEPROM chips to a standard USB flash drive to a USB hardware stone host (if there is one, of course). Well, for hand-made projects, the best option would be the most classic SD card memory card. They come in different types, have different initialization and data transfer mechanisms and connect to the host through various interfaces (however, only three of them, but more on that later). Moreover, many modern microcontrollers have hardware modules of these interfaces on their boards, and the work of the developer is reduced only to their configuration and sending the necessary commands to the card in accordance with the protocol. Well, even memory cards have a pleasant property to be bought at every turn.

About Secure Digital (SD) Cards


I will not rewrite Wikipedia - here I will provide basic information and types of SD memory cards and their characteristics.
Secure Digital format is the most popular (perhaps the most popular today) format of flash memory for use mainly in portable devices. Inside each such card there is, in fact, a flash memory chip (Memory Core) and a controller with 8 registers connecting it with the outside world. The tasks of the latter are hardware implementation of external interfaces, support of information about the card (type, capacity, speed class, a bunch of other characteristics), power control, and, of course, management of the mikrukha memory itself (addressing, reading, writing, cleaning and organizing about 80 control commands ).
')


The SD format was founded by Panasonic, SanDisk and Toshiba based on MMC cards. Later, these companies created the SD Card Association, which is currently engaged in the development and promotion of SD technology. The main document, which describes in detail the interface, protocol, commands, card registers - the Physical Layer Simplified Specification (Copyright 2001-2006 SD Group (Panasonic, SanDisk, Toshiba) and SD Card Association). It is this information that all R & D centers use when developing the hardware and software of their future devices. The file itself is safely available in the internet, and download it does not provide any difficulties. So, in accordance with this document, there are the following types of memory cards:
• SD cards (or else SDSC (Secure Digital Standard Capacity)) - the first generation of memory cards. The limit on the volume - 2 GB. The minimum size of the addressable space is 1 byte.
• SDHC cards (Secure Digital High Capacity) - high-capacity memory cards (up to 32 GB). They have a significant difference from the first type, namely, addressing occurs in blocks of 512 bytes and no one in this world can change this value. In other words, you can’t just take and write, for example, 71 bytes of information: the minimum size of a pack, I repeat, is 512 bytes. I didn’t dig for why, but there is a personal opinion that this is due to the used 32-bit address space of the controller and the fact that memory cards are usually formatted for a particular file system, the cluster size of which is conveniently combined with such blocks. . Another SDHC card arc initialization process, which will talk a bit later on.
• SDXC (Secure Digital eXtended Capacity) - Extended Capacity Memory Cards - theoretically up to 2TB of memory. Addressing is also 512 bytes. So it turns out with 32-bit space: (2 ^ 32) * 512 = 2 TB.

There are specifications for each generation of maps, and at the same time in each document for a newer generation, the information about the old ones is described - that is, they get fat with each update of the product. So download the Physical Layer Simplified Specification of the latest version and find everything you need to work with all generations of cards. In addition, memory cards are divided into several classes according to the speed of reading / writing data. Well, as for all there mini-, microSD, microSDXC, etc. - this is just another body size and pinout - no internal differences from the standard envelope cards.

And now it’s important: OUTSIDE, depending on the card type, capacity, its manufacturer, body type, color, and the store where you bought it - all Security Digital cards have the same interface with the outside world. Commands, initialization mechanisms are different, yes, but the interfaces are the same. This is exactly what allows napofig to insert a SD card and a SDHC memory card into a camera. Well, here we are at the moment to discuss the language of the card, to be exact, as many as three: SD and UHS-II (native speaker) and “the language of universal microprocessor communication, which every uncut dog microcontroller now knows” - SPI .

Memory card interface


As mentioned above, Security Digital cards have three external interfaces: SD, UHS-II and SPI. The first are the “native” data exchange channels with the host, and, as a result, allow you to implement full-featured, full-speed interaction. SPI does not support a number of commands and does not give the maximum data exchange rate, but it is in all microcontrollers (both in modern and old models), which makes it possible to connect a card to everything that does not lie badly without any special problems. There are lots of articles on how to do this. But, with the development of microprocessor technology, with the reduction of nanometers in the technological process of stone production, the SPI interface, as a means of communication with an SD card, is gradually dying out. Indeed, if your MC supports a hardware implementation of the SD protocol, will you get involved in a less functional alternative? Fate sent me a Stm32f4 stone from STMicroelectronics to the project, in which there is just the same peripheral module SDIO (Security Digital Input Output), which implements the interface and card protocol in hardware.

So what is the SD protocol and what is it eaten with? There are three key concepts here:
• command - a sequence of bits perceived by the card controller and calling it for a particular action;
• response - the response of the card controller to the command. It can contain both general information (card status, current state of various internal modules, etc.), and, in fact, the information expected by the host (requested the card ID in the command — received it in response);
• data - well, here without comments.

But before we look at the logic of the protocol, we turn to the interface physics (very clear).


Pin 4 - card power;
Pin 3, 6 - land;
Pin 5 - clock signal;
Pin 2 - a line of commands and responses;
Pin 1, 7, 8, 9 - lines 4-bit data bus.

All parcels to the card and back are sequences of bits strictly synchronized with the clock signal transmitted through the CLK line. Recommended frequencies are described in the card specification and have different meanings, depending on its type and speed class. I will only note that for any card initialization takes place at a very small (compared to data transmission) frequency. The data bus can be 1-bit (only D0 works) or 4-bit — this is configured at initialization. It is important that for the SD cards from the host side, the data lines and commands must be push-pull and be powered up through 4.5-10 kΩ resistors. The clock bus also needs to be pulled up to power.

Well, now to the protocol!

There are several options for exchanging host card information.

1) Commands without data.
All teams are divided into requiring and not requiring a response .



As can be seen from the figure, if we (the host) need to send a command that does not require a response, just send it off. If, however, the team implies a response, a helmet, and then wait for a response. Almost all commands and responses are checked by checksum, both from the host side and from the card side. Well, look at the format of the command:



The frame consists of 48 bits. The first one - the start bit is always zero. Then, we say that the data is sent from the host to the map and send a command with an argument. Yes, yes, the command consists of an index and an argument. After the command, it is necessary to send a 7-bit checksum, calculated according to the cyclic redundancy code (CRC) algorithm, and complete the sending with a stop bit. Commands are of two types: CMD (basic commands) and ACMD (Application-Specific Command) . They can be with and without argument, have a response and not have. In total there are about 80 teams (did not count exactly, maybe more), and each of them is described in detail in the specification. We will focus only on a few, which are necessary for the main work with the card (initialization, reading, writing). The command index is the number that comes after the characters CMD or ACMD. 6 bits and 32 bits of the command argument are reserved for it, if required.

An important explanation about ACMD : the space of their indices intersects with the indexes of the CMD commands, therefore, in order for the controller to perceive the command exactly as Application-Specific, it must be preceded by CMD55 !

Response (if required) is also a whole topic, at least, because there are five types of them.

• R1 (normal response command) - length 48 bits. Perhaps the most popular response.

It contains the start bit, the transmission direction bit (from card to host), 6 bits of the command index that prompted the response, the status of the card and, of course, the checksum with a stop bit. All information in the response of this type is carried by a 32-bit card status field . The specification describes carefully and in good faith what each bit of this status means (the card is busy / free, blocked / unlocked, the current state of the data transfer machine, readiness for a particular action, and much more).

• R1b - the same format as in the case of R1 response, only transmits another busy flag (busy) on the data line.

• R2 (CID, CSD register) - 136-bit-long response sends the contents of the CID and CSD registers of the card controller to the host.

Here, all useful information is contained in a 127-bit field, into which either the content of the CID is placed (in case it is a response to the CMD2 or CMD10 command), or the contents of the CSD register (in the case of sending a CMD9 command). So what are these registers such that special teams are invented for them, and with such a long response?
CID (Card identification data) - as the name implies, contains all identification information about the card (serial number, manufacturer, date of manufacture, etc ...). CSD (Card-specific data) - all technical information about the card (memory size, size of read / write blocks, maximum speed characteristics, maximum characteristics of current consumption in various modes, and much more). It is this information that the mobile or camera host uses to get all the information about the inserted card.

• R3 - 48 bits long, comes as a response to the ACMD41 command and carries information about the contents of the OCR (Operation Conditions Register) of the card register.

ACMD41 - card initialization command. After sending it, you must wait for this response, which will indicate the successful completion of the initialization process and report the contents of the OCR register (available voltage range, type of memory card, and busy flag).

• R6 (Published RCA response) - contains RCA (Relative card address) cards and some status bits.

The bus involves connecting multiple cards to the same host. Therefore, it is very important such a thing as your own card address on the bus. This is the contents of the RCA register.

• R7 (Card interface condition) - 48-bit response to the command CMD8.

The card operates with a certain voltage, no more no less. Before initialization, it is necessary to validate (more on this later). In response, the card sends the voltage itself (more precisely, the value corresponding to this range) and a certain check pattern (this will also be discussed later).

2) Data.
Let me remind you (it was said a long time ago ...), we considered the sending of commands and receiving a response from the card. Now it's time to figure out how to send, in fact, the data. Again, this is done in blocks of 512 bytes (for SDHC cards) - the entire address space of the card is divided into 512 byte cells . Sending data should always be preceded by a special command telling the card controller that the data is just about to go. And they go, as I said - on a 1-bit or 4-bit bus. Let's look at the format of sending data to the host from the card (read).



There are two possible data transfer modes: one block (block read operation) and several blocks at once (multiple block read operation). In any case, the start of the transfer and its completion take place on a special command, note with a response.



The reverse procedure (write) is carried out in a similar way, only between packs the busy is necessarily present, signaling that the card is not ready to accept the next block (the data have not yet been written to the flash cards).

Initializing SD Memory Cards


Well, we, embeds, people are used to everything that needs to be initialized, so the SD card is not an exception to this magnificent rule. You need to check the supported voltages, assign addresses, and generally, make sure that we can work with this card. Let's take a look at the initialization algorithm pulled out of the specification and go through it in order, block by block, in order to understand what needs to be done with the device before using it for its intended purpose.



IMPORTANT : initialization is performed at low speed mode! The frequency of the card clock is not more than 400 kHz !!!

MORE IMPORTANT : after powering up, do not rush to load the card with commands, let the voltage settle down, wait 250 milliseconds (a little longer, depending on the number of cards connected to one bus, data line width and power supply parameters). As soon as the voltage reached the required level, all parasitic capacitances, etc. were charged. etc., you can create an initialization process. And it begins with resetting all the cards and transferring them to Idle State.

• Helmet CMD0 , pay attention, without an argument and do not expect anything in the response. As a result, all the cards on the line will be transferred to idle mode.

• Remember, I said that stress needs to be validated? Right! We need to tell the map what voltage we are working on and listen to everything about it. A CMD8 helmet with an argument in which bits 11: 8 denote host voltage and bits 7: 0 - check pattern (test pattern) - any, the specification recommends sending 10101010 . The voltage bits are set in accordance with the table:



Well, we are all very well defined and far from Low Voltage Range. Stm32f4 gives just the voltage in the range 2.7 - 3.6 V, so we put 1 on the eighth bit of the argument. Total, we have a command with argument 110101010 . Sent. We checked that everything went well and we are waiting for an answer, it will not make us do it for a long time. In the specification, we saw that the answer to this command is the R7 type.
If we did not wait for it, the further ACMD41 team will decide exactly how we were cheated - slipped the card of version 1.X of standard capacity or not an SD card at all. True, there is a possibility that we are just doing something wrong. But let's not talk about sad things, and suppose that the flash drive still answered. If everything is OK with the voltage, the map is satisfied, we are satisfied, the answer will contain everything that we sent in the argument, that is, 110101010 . This is called a valid esponse . If so, proceed to a further step, otherwise - again - either cheated, or somewhere cant.

• We waited for 110101010 , and it was time to directly initialize - the ACMD41 command . And here we remember IMPORTANCE : in order to tell the card that the command is not simple, but ACMD, we will send CMD55 first . In the argument we must indicate the address of the card for which this command is intended. But stop, we have, because, while there is no address, we do not know him. Nothing, we learn ... but later, but for now we write zeros and a helmet. Having received the answer of type R1 , we make sure that the card is ready to accept ACMD and only after that helmet 41 index! The command comes with an argument in which we specify 1 in place of the 30th bit, indicating that the host supports SDHC cards and the host voltage in place of 23: 0 bits (see the contents of the OCR register). The answer is waiting for R3 type. Here it is important for us to get 1 in place of the 31st bit in the response packet that carries the contents of the OCR of the card register (busy flag). This will indicate that the card has completed the initialization process. Seeing that this process takes a long time (much longer than the clock cycle of the microcontroller), it is necessary to send ACMD41 in a loop until we receive a response with the busy flag removed. As soon as this happened, checks are 30 bits, and if it is one, then we have an SDHC or SDXC high capacity card, and an SD standard capacity card otherwise. If we waited, waited, and the bizi flag all hangs and hangs, then, as in the case described above, either the wrong card or (most likely) our joint.

• Further, CMD2 helmet - without an argument and look at the answer R2 . In this case, it will carry information about the contents of the CID register, and we will be able to subtract the manufacturer's ID, serial number of the card and other information.

• And finally, the final step is getting the card address ( RCA - relative
address ). As it was already mentioned, several cards can be connected to one bus, so each one should have its own unique local address. Helmet CMD3 and get a response type R6 , in which in the lower 16 bits contains the status of the card, and in the older - the new RCA address. From now on, to access our card, we will have to call her by name, that is, by RCA address.

• Optional item. By default, the card works with a 1-bit data bus, which, of course, is slower than with a 4-bit data bus. If we want to achieve maximum speed - helmet ACMD6 , with the previous CMD55 , of course. But before that, you need to transfer the card to the Transfer State (see below) with the command CMD7 with RCA as an argument. In the ACMD6 argument , in place of the very first bit, we write 1 - if we want to enable the 4-bit mod and 0 - to disable it. Answer R1 will tell about the success of the operation.

SDHC card initialization example

In this example, a self-made command sending function is used, written under the periphery of Stm32F4.
char SDIO_send_command(char index, unsigned int arg, char resp_type, unsigned int *resp); 

• index - command index;
• arg - argument;
• resp type - response type (0 - no response, 1 - short (48 bit) response, 2 - long (136 bit) response);
• resp - array of responses (in the case of a short response, the information is carried by the first element of the array, in the case of a long one - 4 elements).
• The command returns 0 if the command was sent successfully and received a response and an error code otherwise.

 char SDHC_card_initialization(unsigned int *RCA) { char result; unsigned int RESP[4]; result = SDIO_send_command(0, 0, 0, RESP); // CMD0,    if (result != 0) return result; //   result = SDIO_send_command(8, 0x1AA, 1, RESP); // CMD8   110101010 if ( (result != 0) || (RESP[0] != 0x1AA) ) return 4; //   while( !(RESP[0]&(1<<31) ) ) //,      { result = SDIO_send_command(55, 0, 1, RESP); // CMD55,  , ,    ACMD if (result != 0) return result; result = SDIO_send_command(0x29, 0x40020000, 1, RESP); // ACMD41 if (result != 0) return result; } result = SDIO_send_command(2, 0, 3, RESP); // CMD2      if (result != 0) return result; result = SDIO_send_command(3, 0, 1, RESP); // CMD3   RCA  if (result != 0) return result; SDIO->CLKCR = (0x02<<0)|(1<<11)|(1<<8)|(1<<14); //  (  2 - ) *RCA = ( RESP[0] & (0xFFFF0000) ); //    RCA result = SDIO_send_command(7, *RCA, 1, RESP); //   if (result != 0) return result; result = SDIO_send_command(55, *RCA, 1, RESP); // CMD55,  , ,    ACMD if (result != 0) return result; result = SDIO_send_command(6, 0x02, 1, RESP); // ACMD6 c  0x02,  4-  if (result != 0) return result; if (RESP[0] != 0x920) return 1; else return 0; //,         return 0; } 

We start the code, we are convinced that in the answer the NULL came and we complete initialization. Everything, we can work with memory and write / read information.

Data exchange


Here all drives SD Memory Card State Diagram (data transfer mode).

There are 6 card statuses in this mode and you can recognize them in the R1 response in the place of 12: 9 bits. Refer to the specification.

• Stand by State (stby) - set after initialization instead of Idle State.
• Transfer State (tran) - data transfer mode.
• Receive Data State (rcv) - waiting for a packet of data from the host.
• Programming State (prg) - record of the received packet in flash.
• Sending Data State (data) - sending a packet of data to the host.
• Disconnect State (dis) - used to select another card with the CMD7 command.

Write data to the card

So, after successful initialization, we are in a state of tran , in any case, should be. We look at the diagram: in order to go to the rcv state, we need to send the CMD24 command with the address of 512 byte cells, which we want to write. Have sent. The card went into standby data. Next, we start to throw information to it on the data bus until we transfer all 512 bytes or send the CMD12 (stop transmission) command. After the completion of the act, the card itself will move to the prg state and stay there for some time (until the data is written). We are waiting ... How do we wait? And we send it in the cycle CMD13 with the address of the card in the argument, until the status tran is returned in the R1 type response . When it finally happens, you can send another packet of data by sending CMD24 again. In addition, there is also a recording mode for several blocks at once (CMD25) and other modes - for details - in the specification.

Reading data

In order to perform the reverse procedure, first of all, we make sure that the card is in tran . Helmet CMD17 with RCA address in argument. If everything goes well, the card will move to the data state and will start issuing information on the data lines, again with a 512 byte block. The task of the host at this time carefully listen to the line and read the data. As soon as the parcel is finished, the card itself will move to tran status. I think it’s not necessary to say that reading as well as writing is possible in several blocks at once.

I will not give in this article a listing of the read / write program, since, unlike the initialization subroutine, it is too strongly tied to the SDIO hardware of the Stm32f4 microcontroller module, and this is the topic of the second part of the article.

Literature:
1) SD_Physical_Layer_Spec 2.0
2) SD_Physical_Layer_Spec 4.1
3) STM32F4 CortexM4 Reference manual

Source: https://habr.com/ru/post/213803/


All Articles