Programming SD card

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
catscats
Posts: 2
Joined: Wed Oct 18, 2023 3:08 pm

Programming SD card

Post 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!
Octocontrabass
Member
Member
Posts: 5560
Joined: Mon Mar 25, 2013 7:01 pm

Re: Programming SD card

Post 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.
rdos
Member
Member
Posts: 3296
Joined: Wed Oct 01, 2008 1:55 pm

Re: Programming SD card

Post 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.
catscats
Posts: 2
Joined: Wed Oct 18, 2023 3:08 pm

Re: Programming SD card

Post 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 :-\
Post Reply