#include "board.h" #include "hpm_sdxc_drv.h" #include "hard_sdio_sd.h" // 使用官方的SDMMC例程包 // 修改时要修改初始化io 和时钟 在port文件内 // 这里负责操作初始化IO 和 时钟的接口 注意在port文件填写对应的回调函数 void sdxc_cd_pin(SDXC_Type *ptr, bool as_gpio) { uint32_t cd_pad_ctl = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1); if (ptr == HPM_SDXC1) { /* SDXC1.CDN */ uint32_t cd_func_alt = as_gpio ? IOC_PD28_FUNC_CTL_GPIO_D_28 : IOC_PD28_FUNC_CTL_SDC1_CDN; HPM_IOC->PAD[IOC_PAD_PD28].FUNC_CTL = cd_func_alt; HPM_IOC->PAD[IOC_PAD_PD28].PAD_CTL = cd_pad_ctl; } } uint32_t sd_configure_clock(SDXC_Type *ptr, uint32_t freq, bool need_inverse) { uint32_t actual_freq = 0; do { if (ptr != HPM_SDXC1) { break; } clock_name_t sdxc_clk = (ptr == HPM_SDXC0) ? clock_sdxc0 : clock_sdxc1; sdxc_enable_inverse_clock(ptr, false); sdxc_enable_sd_clock(ptr, false); /* Configure the clock below 400KHz for the identification state */ if (freq <= 400000UL) { clock_set_source_divider(sdxc_clk, clk_src_osc24m, 63); } /* configure the clock to 24MHz for the SDR12/Default speed */ else if (freq <= 26000000UL) { clock_set_source_divider(sdxc_clk, clk_src_osc24m, 1); } /* Configure the clock to 50MHz for the SDR25/High speed/50MHz DDR/50MHz SDR */ else if (freq <= 52000000UL) { clock_set_source_divider(sdxc_clk, clk_src_pll1_clk1, 8); } /* Configure the clock to 100MHz for the SDR50 */ else if (freq <= 100000000UL) { clock_set_source_divider(sdxc_clk, clk_src_pll1_clk1, 4); } /* Configure the clock to 166MHz for SDR104/HS200/HS400 */ else if (freq <= 208000000UL) { clock_set_source_divider(sdxc_clk, clk_src_pll2_clk0, 2); } /* For other unsupported clock ranges, configure the clock to 24MHz */ else { clock_set_source_divider(sdxc_clk, clk_src_osc24m, 1); } if (need_inverse) { sdxc_enable_inverse_clock(ptr, true); } sdxc_enable_sd_clock(ptr, true); actual_freq = clock_get_frequency(sdxc_clk); } while (false); return actual_freq; } void sdxc_cmd_pin(SDXC_Type *ptr, bool open_drain, bool is_1v8) { uint32_t cmd_func_ctl = IOC_PAD_FUNC_CTL_ALT_SELECT_SET(17) | IOC_PAD_FUNC_CTL_LOOP_BACK_SET(1); uint32_t cmd_pad_ctl = IOC_PAD_PAD_CTL_MS_SET(is_1v8) | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1); if (open_drain) { cmd_pad_ctl |= IOC_PAD_PAD_CTL_OD_MASK; } if (ptr == HPM_SDXC1) { /* SDXC1.CMD */ HPM_IOC->PAD[IOC_PAD_PD21].FUNC_CTL = cmd_func_ctl; HPM_IOC->PAD[IOC_PAD_PD21].PAD_CTL = cmd_pad_ctl; } } void sdxc_clk_data_pins(SDXC_Type *ptr, uint32_t width, bool is_1v8) { uint32_t func_ctl = IOC_PAD_FUNC_CTL_ALT_SELECT_SET(17); uint32_t pad_ctl = IOC_PAD_PAD_CTL_MS_SET(is_1v8) | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1); if (ptr == HPM_SDXC1) { /* SDXC1.CLK */ HPM_IOC->PAD[IOC_PAD_PD22].FUNC_CTL = func_ctl; HPM_IOC->PAD[IOC_PAD_PD22].PAD_CTL = pad_ctl; /* SDXC1.DATA0 */ HPM_IOC->PAD[IOC_PAD_PD18].FUNC_CTL = func_ctl; HPM_IOC->PAD[IOC_PAD_PD18].PAD_CTL = pad_ctl; if ((width == 4)) { /* SDXC1.DATA1 */ HPM_IOC->PAD[IOC_PAD_PD17].FUNC_CTL = func_ctl; HPM_IOC->PAD[IOC_PAD_PD17].PAD_CTL = pad_ctl; /* SDXC1.DATA2 */ HPM_IOC->PAD[IOC_PAD_PD27].FUNC_CTL = func_ctl; HPM_IOC->PAD[IOC_PAD_PD27].PAD_CTL = pad_ctl; /* SDXC1.DATA3 */ HPM_IOC->PAD[IOC_PAD_PD26].FUNC_CTL = func_ctl; HPM_IOC->PAD[IOC_PAD_PD26].PAD_CTL = pad_ctl; } } }