hard_sdio_sd.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include "board.h"
  2. #include "hpm_sdxc_drv.h"
  3. #include "hard_sdio_sd.h"
  4. #include "hard_system_delay.h"
  5. // 使用官方的SDMMC例程包
  6. // 修改时要修改初始化io 和时钟 在port文件内
  7. // 这里负责操作初始化IO 和 时钟的接口 注意在port文件填写对应的回调函数
  8. void sdxc1_vsel_pin(SDXC_Type *ptr, bool as_gpio)
  9. {
  10. uint32_t vsel_pad_ctl = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
  11. if (ptr == HPM_SDXC1) {
  12. uint32_t vsel_func_alt = as_gpio ? IOC_PD29_FUNC_CTL_GPIO_D_29 : IOC_PD29_FUNC_CTL_SDC1_VSEL;
  13. HPM_IOC->PAD[IOC_PAD_PD29].FUNC_CTL = vsel_func_alt;
  14. HPM_IOC->PAD[IOC_PAD_PD29].PAD_CTL = vsel_pad_ctl;
  15. }
  16. }
  17. void sdxc1_cd_pin(SDXC_Type *ptr, bool as_gpio)
  18. {
  19. 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);
  20. if (ptr == HPM_SDXC1) {
  21. /* SDXC1.CDN */
  22. uint32_t cd_func_alt = as_gpio ? IOC_PD28_FUNC_CTL_GPIO_D_28 : IOC_PD28_FUNC_CTL_SDC1_CDN;
  23. HPM_IOC->PAD[IOC_PAD_PD28].FUNC_CTL = cd_func_alt;
  24. HPM_IOC->PAD[IOC_PAD_PD28].PAD_CTL = cd_pad_ctl;
  25. }
  26. }
  27. uint32_t sd1_configure_clock(SDXC_Type *ptr, uint32_t freq, bool need_inverse)
  28. {
  29. uint32_t actual_freq = 0;
  30. do {
  31. if (ptr != HPM_SDXC1) {
  32. break;
  33. }
  34. clock_name_t sdxc_clk = (ptr == HPM_SDXC0) ? clock_sdxc0 : clock_sdxc1;
  35. sdxc_enable_inverse_clock(ptr, false);
  36. sdxc_enable_sd_clock(ptr, false);
  37. /* Configure the clock below 400KHz for the identification state */
  38. if (freq <= 400000UL) {
  39. clock_set_source_divider(sdxc_clk, clk_src_osc24m, 63);
  40. }
  41. /* configure the clock to 24MHz for the SDR12/Default speed */
  42. else if (freq <= 26000000UL) {
  43. clock_set_source_divider(sdxc_clk, clk_src_osc24m, 1);
  44. }
  45. /* Configure the clock to 50MHz for the SDR25/High speed/50MHz DDR/50MHz SDR */
  46. else if (freq <= 52000000UL) {
  47. clock_set_source_divider(sdxc_clk, clk_src_pll1_clk1, 8);
  48. }
  49. /* Configure the clock to 100MHz for the SDR50 */
  50. else if (freq <= 100000000UL) {
  51. clock_set_source_divider(sdxc_clk, clk_src_pll1_clk1, 4);
  52. }
  53. /* Configure the clock to 166MHz for SDR104/HS200/HS400 */
  54. else if (freq <= 208000000UL) {
  55. clock_set_source_divider(sdxc_clk, clk_src_pll2_clk0, 2);
  56. }
  57. /* For other unsupported clock ranges, configure the clock to 24MHz */
  58. else {
  59. clock_set_source_divider(sdxc_clk, clk_src_osc24m, 1);
  60. }
  61. if (need_inverse) {
  62. sdxc_enable_inverse_clock(ptr, true);
  63. }
  64. sdxc_enable_sd_clock(ptr, true);
  65. actual_freq = clock_get_frequency(sdxc_clk);
  66. } while (false);
  67. return actual_freq;
  68. }
  69. void sdxc1_cmd_pin(SDXC_Type *ptr, bool open_drain, bool is_1v8)
  70. {
  71. uint32_t cmd_func_ctl = IOC_PAD_FUNC_CTL_ALT_SELECT_SET(17) | IOC_PAD_FUNC_CTL_LOOP_BACK_SET(1);
  72. 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) |
  73. IOC_PAD_PAD_CTL_PS_SET(1);
  74. if (open_drain) {
  75. cmd_pad_ctl |= IOC_PAD_PAD_CTL_OD_MASK;
  76. }
  77. if (ptr == HPM_SDXC1) {
  78. /* SDXC1.CMD */
  79. HPM_IOC->PAD[IOC_PAD_PD21].FUNC_CTL = cmd_func_ctl;
  80. HPM_IOC->PAD[IOC_PAD_PD21].PAD_CTL = cmd_pad_ctl;
  81. }
  82. }
  83. void sdxc1_clk_data_pins(SDXC_Type *ptr, uint32_t width, bool is_1v8)
  84. {
  85. uint32_t func_ctl = IOC_PAD_FUNC_CTL_ALT_SELECT_SET(17);
  86. 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) |
  87. IOC_PAD_PAD_CTL_PS_SET(1);
  88. if (ptr == HPM_SDXC1) {
  89. /* SDXC1.CLK */
  90. HPM_IOC->PAD[IOC_PAD_PD22].FUNC_CTL = func_ctl;
  91. HPM_IOC->PAD[IOC_PAD_PD22].PAD_CTL = pad_ctl;
  92. /* SDXC1.DATA0 */
  93. HPM_IOC->PAD[IOC_PAD_PD18].FUNC_CTL = func_ctl;
  94. HPM_IOC->PAD[IOC_PAD_PD18].PAD_CTL = pad_ctl;
  95. if ((width == 4)) {
  96. /* SDXC1.DATA1 */
  97. HPM_IOC->PAD[IOC_PAD_PD17].FUNC_CTL = func_ctl;
  98. HPM_IOC->PAD[IOC_PAD_PD17].PAD_CTL = pad_ctl;
  99. /* SDXC1.DATA2 */
  100. HPM_IOC->PAD[IOC_PAD_PD27].FUNC_CTL = func_ctl;
  101. HPM_IOC->PAD[IOC_PAD_PD27].PAD_CTL = pad_ctl;
  102. /* SDXC1.DATA3 */
  103. HPM_IOC->PAD[IOC_PAD_PD26].FUNC_CTL = func_ctl;
  104. HPM_IOC->PAD[IOC_PAD_PD26].PAD_CTL = pad_ctl;
  105. }
  106. }
  107. }