2
\$\begingroup\$

Overview

I'm using a STM32F407ZGT6 and I'm currently trying to mount SD cards (MicroSD 32GB HCI and 256GB XCI picture) to the board using the FATFS library bare-metal. To handle low level I/O, I'm using colosimo's code (diskio_stm32f4xx.c).

Setup

Edit: My initialization clock is 400kHz and then it's set to 4MHz. Below is my circuit via SD adapter with 10K ohms: Micro SD to SD adapter circuit

The problem

Edit: On my previous edit, I noticed I wasn't setting SDIO_DCTRL_SDIOEN nor SDIO_DCTRL_RWSTART, therefore STBITERR was being raised. Unfortunately, I currently can't enable the SDIO_STA_RXDAVL bit on SDIO->STA which indicates there is no data avaialbe in the FIFO, as indicated in the comments below:

cmd = (count > 1) ? 18 : 17;
t = msTicks;
rd = 0;

SDIO->DCTRL = ((0b1001 << 4) | SDIO_DCTRL_DTDIR);
SDIO->DLEN = (512 * count);
SDIO->DTIMER = (400000);

sta = 0;
if (!send_cmd(cmd, sector, RESP_SHORT, &resp) || (resp & 0xc0580000))   /*!MOD REG?*/
    return RES_ERROR;
SDIO->ICR = (0xFF);
SDIO->DCTRL |= (SDIO_DCTRL_SDIOEN   | //<<---Newly set bits
                SDIO_DCTRL_RWSTART  |
                SDIO_DCTRL_DTDIR    |
                SDIO_DCTRL_DTEN
               );

while (elapsed(t) < 1000){

    sta = SDIO->STA;

    if (sta & (SDIO_STA_DTIMEOUT | SDIO_STA_RXOVERR | SDIO_STA_STBITERR)) {
        err("%s SDIO_STA: 0x%08X\n", __func__, (uint)sta);
        break;
    }

    if (sta & SDIO_STA_RXFIFOE)
        continue;

    if (rd == 0 && !(sta & SDIO_STA_RXDAVL))
        continue;      //<<---No data available, so can't get to FIFO

    data = SDIO->FIFO; //<<---Never gets here

    buf[rd++] = data;
    buf[rd++] = data >> 8;
    buf[rd++] = data >> 16;
    buf[rd++] = data >> 24;


    if (rd == 512 * count)
        break;
}

if (rd < 512 * count || cmd == 18)
    send_cmd(12, 0, RESP_SHORT, &resp);

return SDIO->DCOUNT ? RES_ERROR : RES_OK;

What am I forgetting? How can I make data available?

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

I finally got it fixed! My problem was with the hardware. Although I cannot put a finger on what was the problem, I'll guess that the SD adapter was broken or had a weird pinout. Also, having only the internal GPIOs pull-ups (30k to 50k Ohms) was enough and I didn’t need the physical resistors I was adding to the circuit.

Moreover, my breaking points were generating weird results since the SD is a microprocessor itself. Therefore, every breakpoint would influence clocks and couters from the SD and the were messing up my debugging. Once I got them out of the way, the response came out positive using the embedded SD slot that came with my board.

Another problem that I found was that only the FAT32 card was accepted. ExFAT cards did not get recognized, always returning FR_NO_FILESYSTEM. Below the output of all my testing conditions:

Card Type Circuit Type GPIO_PUPDR Response
FAT32 Embedded Circuit Pull-Up FR_OK
FAT32 Embedded Circuit *Pull-No FR_NOT_READY
FAT32 *SD Adapter Circuit Any FR_DISK_ERR
*ExFAT Embedded Circuit Any FR_NO_FILESYSTEM

* The main factors that caused errors on each combination

\$\endgroup\$
0
\$\begingroup\$

Not an absolute answer, but some issues/suggestions ...

It helps to separate concerns:

  1. Does the raw diskio package talk to the disk device?
  2. Most FS software on development systems (that presumably create the initial FS image) want a partition table (e.g. MBR or GPT). Do you need one?
  3. Does the FS library talk to the disk library correctly?
  4. What FATFS are you using (e.g. FAT16, FAT32)?
  5. What sort of debug capability do you have (e.g. gdb or other STM32 specific debugger)?

So, I'd write a diagnostic that exercises the disk on the STM32 without regard to whether there is a FS on it or not. That is, write some data to the [raw] disk. Can you read it back correctly? Don't bother with the FS layer until you're convinced that the disk layer accesses the device correctly.

Then, when you're convinced the raw disk I/O works, answer the question whether you need a partition table.

It's not absolutely necessary. But, it allows the disk to [more easily] be plugged into a development system to create the FS, put some files on it, and later verify what the STM32 has done to the disk.

So, using a development system, create the FS image. Put the SD card in the target (STM32) system. With a known good FS image, then that should help you determine whether the FS layer is talking to the disk.

The FS layer should be seeing the valid FS image. If not, either it is not connected to the disk I/O layer correctly or it perceives the FS image to be bad.

On the development system, you should be able to get a hex dump of the image.

Presumably (hopefully) you can get the disk I/O layer to dump the raw data to the UART/screen in hex.

Again, it should be possible to get the FS layer to do the same. The data should match at all layers of the process.

\$\endgroup\$
1
  • \$\begingroup\$ The SD is actually responding now, but for some reason I'm getting that nasty STBITERR. Any ideas why? \$\endgroup\$
    – mgmussi
    Aug 18, 2022 at 19:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.