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?

  • 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.

Related