1 /* 2 * Copyright (c) 2021-2023 HPMicro 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 8 #ifndef HPM_SDMMC_COMMON_H 9 #define HPM_SDMMC_COMMON_H 10 11 #include "hpm_common.h" 12 #include "hpm_sdmmc_card.h" 13 #include "hpm_sdmmc_host.h" 14 15 /****************************************************************** 16 * 17 * @brief SD/MMC Typical Clock frequency definitions 18 * 19 ******************************************************************/ 20 #define SDMMC_CLOCK_400KHZ (400000UL) 21 #define SD_CLOCK_25MHZ (25000000UL) 22 #define SD_CLOCK_50MHZ (50000000UL) 23 #define SD_CLOCK_100MHZ (100000000UL) 24 #define SD_CLOCK_208MHZ (208000000UL) 25 26 #define MMC_CLOCK_26MHz (26000000UL) 27 #define MMC_CLOCK_52MHz (52000000UL) 28 #define MMC_CLOCK_DDR52 (52000000UL) 29 #define MMC_CLOCK_HS200 (200000000UL) 30 #define MMC_CLOCK_HS400 (200000000UL) 31 32 enum { 33 sdmmc_state_idle = 0, 34 sdmmc_state_ready = 1, 35 sdmmc_state_identify = 2, 36 sdmmc_state_standby = 3, 37 sdmmc_state_transfer = 4, 38 sdmmc_state_send_data = 5, 39 sdmmc_state_receive_data = 6, 40 sdmmc_state_program = 7, 41 sdmmc_state_disconnect = 8 42 }; 43 44 typedef enum { 45 sdmmc_operation_voltage_1v8 = 5, 46 sdmmc_operation_voltage_3v0 = 6, 47 sdmmc_operation_voltage_3v3 = 7, 48 } sdmmc_operation_voltage_t; 49 50 51 typedef enum { 52 sdmmc_resp_none = 0, 53 sdmmc_resp_r1, 54 sdmmc_resp_r1b, 55 sdmmc_resp_r2, 56 sdmmc_resp_r3, 57 sdmmc_resp_r4, 58 sdmmc_resp_r5, 59 sdmmc_resp_r5b, 60 sdmmc_resp_r6, 61 sdmmc_resp_r7, 62 } sdmmc_resp_type_t; 63 64 enum { 65 status_sdmmc_card_not_support = MAKE_STATUS(status_group_sdmmc, 0), 66 status_sdmmc_wait_card_insert_timeout = MAKE_STATUS(status_group_sdmmc, 1), 67 status_sdmmc_no_sd_card_inserted = MAKE_STATUS(status_group_sdmmc, 2), 68 status_sdmmc_device_init_required = MAKE_STATUS(status_group_sdmmc, 3), 69 status_sdmmc_wait_busy_timeout = MAKE_STATUS(status_group_sdmmc, 4), 70 71 }; 72 73 #ifdef __cplusplus 74 extern "C" { 75 #endif 76 77 /** 78 * @brief Switch device to Idle state 79 * @param [in/out] host SD/MMC Host Context 80 * @param [in] argument Argument for CMD0 81 * @return status_success if operation is successful 82 */ 83 hpm_stat_t sdmmc_go_idle_state(sdmmc_host_t *host, uint32_t argument); 84 /** 85 * @brief Switch device to Inactive state 86 * @param [in/out] host SD/MMC Host Context 87 * @param [in] relative_addr device relative address 88 * @return status_succes if operation is successful 89 */ 90 hpm_stat_t sdmmc_go_inactive_state(sdmmc_host_t *host, uint16_t relative_addr); 91 /** 92 * @brief Select/De-select the device 93 * @param [in/out] host SD/MMC Host Context 94 * @param [in] relative_addr device relative address 95 * @param [in] is_selected true: select, false: de-select 96 * @return status_success if operation is successful 97 */ 98 hpm_stat_t sdmmc_select_card(sdmmc_host_t *host, uint16_t relative_addr, bool is_selected); 99 /** 100 * @brief Send Application Command 101 * @param [in/out] host SD/MMC Host Context 102 * @param [in] relative_addr device related address 103 * @return status_success if operation is successful 104 */ 105 hpm_stat_t sdmmc_send_application_command(sdmmc_host_t *host, uint16_t relative_addr); 106 /** 107 * @brief Set block count 108 * @param [in/out] host SD/MMC Host Context 109 * @param [in] block_count SD/MMC Block count 110 * @return status_success if operation is successful 111 */ 112 hpm_stat_t sdmmc_set_block_count(sdmmc_host_t *host, uint32_t block_count); 113 /** 114 * @brief Set Block size 115 * @param [in/out] host SD/MMC Host Context 116 * @param [in] block_size SD/MMC Block size 117 * @return status_success if operation is successful 118 */ 119 hpm_stat_t sdmmc_set_block_size(sdmmc_host_t *host, uint32_t block_size); 120 121 /** 122 * @brief Enable Auto Tuning mode 123 * @param [in/out] host SD/MMC Host Context 124 * @return status_success if operation is successful 125 */ 126 hpm_stat_t sdmmc_enable_auto_tuning(sdmmc_host_t *host); 127 128 /** 129 * @brief Extract Fields from raw CSD data 130 * @param [in] raw_csd Raw CSD data array 131 * @param [in] end_offset end offset of the specific field (in terms of bit) 132 * @param [in] start_offset start offset of the specific field (in terms of bit) 133 * @return Extracted CSD field 134 */ 135 uint32_t extract_csd_field(const uint32_t *raw_csd, uint8_t end_offset, uint8_t start_offset); 136 137 /** 138 * @brief Get System address 139 * @param [in] host SD/MMC Host Context 140 * @param [in] addr memory address 141 * @return Converted system address 142 */ 143 extern uint32_t sdmmc_get_sys_addr(sdmmc_host_t *host, uint32_t addr); 144 145 146 #ifdef __cplusplus 147 } 148 #endif 149 150 151 #endif /* HPM_SDMMC_COMMON_H */ 152