This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

fatfs example doesn't work with SDHC

Hi

I am using fafs example from SDK 15.0.0

It was possible to write to the SD card by SPI communication.
However, using SanDisk's 32GBSDHC, it became impossible to write.
Do fatfsexample is not me to the discrimination of SD and SDHC automatically?

Parents
  • There are differences in the initialization of SD and SDHC cards. SDHC is not currently supported by the fatfs example.

  • Thank you for your reply!

    So should I change the sdc_cmd in the code from line 510 to line 634 of "app_sdcard.c"?

    static PT_THREAD(sdc_pt_identification(uint8_t * p_rx_data,
                                           uint8_t rx_length,
                                           sdc_result_t * p_exit_code))
    {
        uint8_t r1   = p_rx_data[0];
        uint32_t rsp = ((uint32_t)p_rx_data[1] << 24)
                       | ((uint32_t)p_rx_data[2] << 16)
                       | ((uint32_t)p_rx_data[3] << 8)
                       | ((uint32_t)p_rx_data[4]);
        uint32_t arg;
        ret_code_t err_code;
        sdc_result_t sub_exit_code;
    
        PT_BEGIN(SDC_PT);
        while (1)
        {
            err_code = sdc_cmd(CMD0, 0, SDC_R1);
            APP_ERROR_CHECK(err_code);
            PT_YIELD(SDC_PT);
            err_code = sdc_cmd(CMD0, 0, SDC_R1);
            APP_ERROR_CHECK(err_code);
            PT_YIELD(SDC_PT);
    
            SDC_RESP_CHECK(SDC_PT, r1);
            // Send CMD8 with fixed argument - 0x01AA.
            err_code = sdc_cmd(CMD8, 0x1AA, SDC_R7);
            APP_ERROR_CHECK(err_code);
            PT_YIELD(SDC_PT);
    
            if (!(r1 & SDC_FLAG_ILLEGAL_COMMAND))
            {
                // CMD8 was accepted - SD v2 card.
                m_cb.info.type.version = SDC_TYPE_SDV2;
                SDC_RESP_CHECK(SDC_PT, r1);
            }
    
            m_cb.state.retry_count = 0;
            arg = (m_cb.info.type.version == SDC_TYPE_SDV2) ? SDC_HCS_FLAG_MASK : 0;
            err_code = sdc_cmd(ACMD41, arg, SDC_R3);
            APP_ERROR_CHECK(err_code);
            PT_YIELD(SDC_PT);
    
            if (r1 & SDC_FLAG_ILLEGAL_COMMAND)
            {
                // ACMD41 was rejected - MMC card.
                m_cb.info.type.version = SDC_TYPE_MMCV3;
                r1 &= ~SDC_FLAG_ILLEGAL_COMMAND;
    
                do
                {
                    ++m_cb.state.retry_count;
                    if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT_INIT)
                    {
                        SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT);
                    }
    
                    err_code = sdc_cmd(CMD1, 0, SDC_R3);
                    APP_ERROR_CHECK(err_code);
                    PT_YIELD(SDC_PT);
                    SDC_RESP_CHECK(SDC_PT, r1);
                }
                while (r1 & SDC_FLAG_IN_IDLE_STATE);
            }
            else
            {
                // SDv1 or SDv2 card. Send CMD58 or retry ACMD41 if not ready.
                SDC_RESP_CHECK(SDC_PT, r1);
    
                while (r1 & SDC_FLAG_IN_IDLE_STATE)
                {
                    ++m_cb.state.retry_count;
                    if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT_INIT)
                    {
                        SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT);
                    }
    
                    arg = (m_cb.info.type.version == SDC_TYPE_SDV2) ? SDC_HCS_FLAG_MASK : 0;
                    err_code = sdc_cmd(ACMD41, arg, SDC_R3);
                    APP_ERROR_CHECK(err_code);
                    PT_YIELD(SDC_PT);
                    SDC_RESP_CHECK(SDC_PT, r1);
                }
    
                err_code = sdc_cmd(CMD58, 0, SDC_R3);
                APP_ERROR_CHECK(err_code);
                PT_YIELD(SDC_PT);
                SDC_RESP_CHECK(SDC_PT, r1);
    
                if (rsp & SDC_HCS_FLAG_MASK)
                {
                    m_cb.info.type.sdhc = 1;
                }
            }
    
            if (m_cb.info.type.version != SDC_TYPE_SDV2)
            {
                // Set block length to 512 (SDv1 and MMC cards only.)
                err_code = sdc_cmd(CMD16, SDC_SECTOR_SIZE, SDC_R1);
                APP_ERROR_CHECK(err_code);
                PT_YIELD(SDC_PT);
                SDC_RESP_CHECK(SDC_PT, r1);
            }
    
            // Setup the read operation and get the contents of 128-bit CSD register.
            m_cb.state.rw_op.buffer = m_cb.work_buf;
            m_cb.state.rw_op.block_count = 1;
    
            err_code = sdc_cmd(CMD9, 0, SDC_R1);
            APP_ERROR_CHECK(err_code);
            PT_YIELD(SDC_PT);
            SDC_RESP_CHECK(SDC_PT, r1);
    
            p_rx_data += SDC_R1_LEN;
            rx_length -= SDC_R1_LEN;
            PT_SPAWN(SDC_PT, SDC_PT_SUB, sdc_pt_sub_data_read(p_rx_data, rx_length, \
                                                              16, &sub_exit_code));
            SDC_RESULT_CHECK(SDC_PT, sub_exit_code);
    
            m_cb.info.num_blocks = sdc_calculate_size(m_cb.work_buf);
            m_cb.info.block_len  = SDC_SECTOR_SIZE;
    
            SDC_BREAK(SDC_PT, SDC_SUCCESS);
        }
        PT_END(SDC_PT)
    }

  • I read the program, but you've judged whether it's SDHC, right?
    What is missing to actually enable SDHC?

  • As the example code don't support SDHC cards, you either have use a SD card, or change the code yourself. Use the info in the link in my first answer and check is there are more info elsewhere.

  • I understand. I'll give it a try.

    I have one thing to worry about,
    I think it is necessary to send 74 bytes of dummy data as the SD card initialization procedure, but this code does not find that description.
    Where is the code to send dummy data?
    Or do I have to write?

    And there ’s another area I ’m interested in,
    Is it not necessary to ASSERT or DEASSERT CS before and after using sdc_cmd ()?

  • I think it's 74 clock cycles, not bytes. That should be in the code. 

    The CS pin is handled by the library, there shouldn't be any need to change this. You just change the pin to suit your config, see documentation

  • Thank you!
    It worked well by sending a dummy clock

Reply Children
No Data
Related