12.3 EXTUN (Execute Tuning) status issue

After starting a tuning procedure by setting the SDMMC_HC2R.EXTUN bit, this bit is not automatically cleared when the tuning procedure is completed.

Work Around

Do not wait for SDMMC_HC2R.EXTUN to be cleared. Launching 17 iterations of the tuning command always finalizes the tuning procedure.

Example:

//FIX: Tuning procedure

enum tuning_status {TUNING_SUCCEED, TUNING_FAIL};
enum tuning_status st;

// Start the tuning procedure
#ifdef EMMC_MODE
// e.MMC Mode
pSDMMC->SDMMC_HC2R |= SDMMC_HC2R_EMMC_EXTUN_1;
#else
// SD/SDIO mode
pSDMMC->SDMMC_HC2R |= SDMMC_HC2R_SD_SDIO_EXTUN_1;
#endif
do {
   / Reset the tuning procedure /
   pSDMMC->SDMMC_HC2R &= ~(SDMMC_HC2R_SCLKSEL_1 | SDMMC_HC2R_EMMC_EXTUN_1);
   while((pSDMMC->SDMMC_HC2R & SDMMC_HC2R_EMMC_EXTUN_Msk) == SDMMC_HC2R_EMMC_EXTUN_1);
// Tuning procedure is always completed after 17 executions of the tuning command
for (ix = 0; ix < 17; ix++) {

#ifdef EMMC_MODE
   // e.MMC Mode : command SEND_TUNING_BLOCK (CMD21)
   send_cmd21();
#else
   // SD/SDIO mode : command SEND_TUNING_PATTERN (CMD19)
   send_cmd19();
#endif
   // Wait for BRDRDY status to be set
   while (!(pSDMMC->SDMMC_NISTR & SDMMC_NISTR_BRDRDY_Msk)); 
   // Clear BRDRDY status bit
   pSDMMC->SDMMC_NISTR = SDMMC_NISTR_BWRRDY_0;
}
} while((pSDMMC->SDMMC_HC2R & SDMMC_HC2R_EMMC_EXTUN_Msk) == SDMMC_HC2R_EMMC_EXTUN_1); 
// Check if tuning failed
if (!(pSDMMC->SDMMC_HC2R & SDMMC_HC2R_SCLKSEL_1))
   // Tuning failed
   st = TUNING_FAIL;
else
   // Tuning successful
   st = TUNING_SUCCEED;

// Clear residual interrupts, if any
if (pSDMMC->SDMMC_NISTR & SDMMC_NISTR_ERRINT_1)
    pSDMMC->SDMMC_EISTR = pSDMMC->SDMMC_EISTR;

// Clear residual status, if any
pSDMMC->SDMMC_NISTR = pSDMMC->SDMMC_NISTR;

Affected Device Revisions

A0

A0-D1G

A0-D2G

A1

A1-D5M

A1-D1G

A1-D2G

A1-D4G

XX