/* Sets the SD bus clock speed */ void IP_SDMMC_SetClock(IP_SDMMC_001_T *pSDMMC, uint32_t clk_rate, uint32_t speed) { /* compute SD/MMC clock dividers */ uint32_t div; div = ((clk_rate / speed) + 2) >> 1; if ((div == pSDMMC->CLKDIV) && pSDMMC->CLKENA) { return; /* Closest speed is already set */ } /* disable clock */ pSDMMC->CLKENA = 0; /* User divider 0 */ pSDMMC->CLKSRC = MCI_CLKSRC_CLKDIV0; /* inform CIU */ IP_SDMMC_SendCmd(pSDMMC, MCI_CMD_UPD_CLK | MCI_CMD_PRV_DAT_WAIT, 0); /* set divider 0 to desired value */ pSDMMC->CLKDIV = MCI_CLOCK_DIVIDER(0, div); /* inform CIU */ IP_SDMMC_SendCmd(pSDMMC, MCI_CMD_UPD_CLK | MCI_CMD_PRV_DAT_WAIT, 0); /* enable clock */ pSDMMC->CLKENA = MCI_CLKEN_ENABLE; /* inform CIU */ IP_SDMMC_SendCmd(pSDMMC, MCI_CMD_UPD_CLK | MCI_CMD_PRV_DAT_WAIT, 0); }
/*********************************************************************//** * @brief Function to set speed of the clock going to card * @param[in] speed Desired clock speed to the card * @return None **********************************************************************/ void sdif_set_clock(uint32_t speed) { /* compute SD/MMC clock dividers */ uint32_t div; /* Exit if the clock is already set at the passed speed */ if (sdif_dev.sdif_slot_clk_rate == speed) return; div = ((sdif_dev.sdio_clk_rate / speed) + 2) >> 1; sdif_dev.sdif_slot_clk_rate = speed; if ((div == LPC_SDMMC->CLKDIV) && LPC_SDMMC->CLKENA) return; /* Closest speed is already set */ /* disable clock */ LPC_SDMMC->CLKENA = 0; /* User divider 0 */ LPC_SDMMC->CLKSRC = MCI_CLKSRC_CLKDIV0; /* inform CIU */ sdif_send_cmd(MCI_CMD_UPD_CLK | MCI_CMD_PRV_DAT_WAIT, 0); /* set divider 0 to desired value */ LPC_SDMMC->CLKDIV = MCI_CLOCK_DIVIDER(0, div); /* inform CIU */ sdif_send_cmd(MCI_CMD_UPD_CLK | MCI_CMD_PRV_DAT_WAIT, 0); /* enable clock */ LPC_SDMMC->CLKENA = MCI_CLKEN_ENABLE; /* inform CIU */ sdif_send_cmd(MCI_CMD_UPD_CLK | MCI_CMD_PRV_DAT_WAIT, 0); }