Microchip-MPLAB-Harmony / core

Harmony 3 Core
https://onlinedocs.microchip.com/v2/keyword-lookup?keyword=MH3_core&redirect=true
Other
15 stars 12 forks source link

drv_sdmmc: EMMC high speed mode setting never successes #39

Open picerno76 opened 3 days ago

picerno76 commented 3 days ago

it never successes because lDRV_SDMMC_SetClock needs to be called more times before return DRV_SDMMC_CLOCK_SET_COMPLETE, so it immediately goes to the DRV_SDMMC_INIT_ERROR state

case DRV_SDMMC_INIT_SET_EMMC_HS_FREQ:
...
...
...
    lDRV_SDMMC_SetClock (dObj, DRV_SDMMC_CLOCK_FREQ_HS_52_MHZ);
    if (dObj->clockState == DRV_SDMMC_CLOCK_SET_COMPLETE)
    {
        dObj->cardCtxt.currentSpeed = DRV_SDMMC_CLOCK_FREQ_HS_52_MHZ;
        dObj->sdmmcPlib->sdhostSetSpeedMode (DRV_SDMMC_SPEED_MODE_HIGH);
        dObj->initState = DRV_SDMMC_INIT_SET_BLOCK_LENGTH;
    }
    else
    {
        dObj->initState = DRV_SDMMC_INIT_ERROR;
    }

if you like it, I fixed this way:

case DRV_SDMMC_INIT_SET_EMMC_HS_FREQ:
    {
        lDRV_SDMMC_CommandSend (dObj,
                    (uint8_t)DRV_SDMMC_CMD_SWITCH,
                    DRV_SDMMC_SWITCH_HS_ARGU,
                    (uint8_t)DRV_SDMMC_CMD_RESP_R1B,
                    &dObj->dataTransferFlags);
        if (dObj->cmdState == DRV_SDMMC_CMD_EXEC_IS_COMPLETE)
        {
            if (dObj->commandStatus == DRV_SDMMC_COMMAND_STATUS_SUCCESS)
            {
                dObj->initState = DRV_SDMMC_INIT_SET_HS_FREQ;
            }
            else
            {
                dObj->initState = DRV_SDMMC_INIT_ERROR;
            }
        }
        break;
    }

case DRV_SDMMC_INIT_SET_HS_FREQ:
    lDRV_SDMMC_SetClock (dObj, dObj->protocol == DRV_SDMMC_PROTOCOL_SD ? DRV_SDMMC_CLOCK_FREQ_HS_50_MHZ : DRV_SDMMC_CLOCK_FREQ_HS_52_MHZ);
    if (dObj->clockState == DRV_SDMMC_CLOCK_SET_COMPLETE)
    {
        dObj->cardCtxt.currentSpeed = dObj->protocol == DRV_SDMMC_PROTOCOL_SD ? DRV_SDMMC_CLOCK_FREQ_HS_50_MHZ : DRV_SDMMC_CLOCK_FREQ_HS_52_MHZ;
        dObj->sdmmcPlib->sdhostSetSpeedMode (DRV_SDMMC_SPEED_MODE_HIGH);
        dObj->initState = DRV_SDMMC_INIT_SET_BLOCK_LENGTH;
    }
    break;

pay attention to set REFCLKO4 to 52Mhz or a multiple value of it, otherwise it sets a wrong frequency.