Page 1 of 1

Programming SD card

Posted: Wed Oct 18, 2023 3:39 pm
by catscats
Hi,

I got stuck at reading sector 0 of the card from Realtek SD card reader (5260). I send READ_SINGLE_BLOCK (0x11) command to the controller. Here is the code:

Code: Select all

    init_cmd(hDev);

    add_cmd(hDev, WRITE_REG, 0xFDA9, 0xFFu, 0x51u); //SD_CMD0
    add_cmd(hDev, WRITE_REG, 0xFDAA, 0xFFu, 0); //SD_CMD1
    add_cmd(hDev, WRITE_REG, 0xFDAB, 0xFFu, 0); //SD_CMD2
    add_cmd(hDev, WRITE_REG, 0xFDAC, 0xFFu, 0); //SD_CMD3
    add_cmd(hDev, WRITE_REG, 0xFDAD, 0xFFu, 0); //SD_CMD4

    add_cmd(hDev, WRITE_REG, 0xFDAF, 0xFFu, 0x0); //SD_BYTE_CNT_L
    add_cmd(hDev, WRITE_REG, 0xFDB0, 0xFFu, 0x2); //SD_BYTE_CNT_H
    add_cmd(hDev, WRITE_REG, 0xFDB1, 0xFFu, 0x1); //SD_BLOCK_CNT_L
    add_cmd(hDev, WRITE_REG, 0xFDB2, 0xFFu, 0x0); //SD_BLOCK_CNT_H

    add_cmd(hDev, WRITE_REG, 0xFDA0, 0x3u, 0x1); //SD_CFG1 : bus width

    add_cmd(hDev, WRITE_REG, 0xFDA1, 0xFFu, 0x1); //SD_CFG2 : 1 : SD_RSP_TYPE_R1
    add_cmd(hDev, WRITE_REG, 0xFD5B, 1, 1); //CARD_DATA_SOURCE : 1 : RTSX_PINGPONG_BUFFER

    add_cmd(hDev, WRITE_REG, 0xFDB3, 0xFFu, 0x80 | 0xC); //SD_TRANSFER : SD_TRANSFER_START | SD_TM_NORMAL_READ
    add_cmd(hDev, CHECK_REG, 0xFDB3, 0x40u, 0x40); //SD_TRANSFER : SD_TRANSFER_END

    send_cmd(hDev);
After sending command 17 I read from the ping pong buffer:

Code: Select all

    init_cmd(hDev);
    DWORD reg = 0xFA00;
    for (DWORD i = 0; i < 0x100; i++)
    {
        add_cmd(hDev, 0, reg, 0, 0);
        reg++;
    }
    send_cmd(hDev);
After executing the code above, the command buffer of the controller becomes filled with zeroes, which is definitely not the expected content of the first sector of the card. At the moment, I am completely out of ideas regarding what might be wrong with the code, don't even have an approach to debug the issue. Any help?

Thanks!

Re: Programming SD card

Posted: Sun Oct 22, 2023 8:05 pm
by Octocontrabass
Have you tried looking at other drivers to see what they do differently? I notice the value you've selected for SD_CFG2 is very different from the value used by the Linux driver, for example.

Re: Programming SD card

Posted: Mon Oct 23, 2023 12:00 pm
by rdos
The boot sector containing all zeros is not impossible. One of my NVMe discs had all zeroes on the boot sector.

Also, setting up the SD card is pretty complicated, having to account for different modes and "standards". Without that done properly, you will either get incorrect data or operations that work at sub-optimal speed.

Re: Programming SD card

Posted: Mon Oct 23, 2023 4:51 pm
by catscats
Have you tried looking at other drivers to see what they do differently? I notice the value you've selected for SD_CFG2 is very different from the value used by the Linux driver, for example.
I did. And I don't understand what is wrong with my code. I derived the code from disassembling/decompiling of the official driver. As of SD_CFG2 register the effective value is 1 because SD_CALCULATE_CRC7, SD_CHECK_CRC16, SD_NO_WAIT_BUSY_END, SD_CHECK_CRC7 and SD_RSP_LEN_6 are actually 0 and SD_RSP_LEN_6 is 1.
Without that done properly, you will either get incorrect data or operations that work at sub-optimal speed
For the moment I would be happy to make it work even at sub-optimal speed :)


One thing that I noticed looking at the log of the official driver: in case of data transfer, the value of BIER register has DATA_DONE_INT bit set, while my commands do generate interrupts but never cause the device to set the bit. I only get CMD_DONE_INT and TRANS_OK_INT bits in BIER. No idea why :-\