hard_sdio_sd.c 4.0 KB

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