1 //*****************************************************************************
2 //
3 //! @file am_hal_card_host.h
4 //!
5 //! @brief Functions for interfacing with the SDHC or SPI SD/MMC/SDIO card host.
6 //!
7 //! @addtogroup card_host_4p Card Host for SD/MMC/eMMC/SDIO
8 //! @ingroup apollo4p_hal
9 //! @{
10 //
11 //*****************************************************************************
12 
13 //*****************************************************************************
14 //
15 // Copyright (c) 2023, Ambiq Micro, Inc.
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are met:
20 //
21 // 1. Redistributions of source code must retain the above copyright notice,
22 // this list of conditions and the following disclaimer.
23 //
24 // 2. Redistributions in binary form must reproduce the above copyright
25 // notice, this list of conditions and the following disclaimer in the
26 // documentation and/or other materials provided with the distribution.
27 //
28 // 3. Neither the name of the copyright holder nor the names of its
29 // contributors may be used to endorse or promote products derived from this
30 // software without specific prior written permission.
31 //
32 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
36 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 // POSSIBILITY OF SUCH DAMAGE.
43 //
44 // This is part of revision release_sdk_4_4_0-3c5977e664 of the AmbiqSuite Development Package.
45 //
46 //*****************************************************************************
47 #ifndef AM_HAL_CARD_HOST_H
48 #define AM_HAL_CARD_HOST_H
49 
50 #ifdef __cplusplus
51 extern "C"
52 {
53 #endif
54 
55 //
56 //! SD/MMC/SDIO host instance index
57 //
58 typedef enum
59 {
60     AM_HAL_SDHC_CARD_HOST,
61     AM_HAL_CARD_HOST_NUM ,
62 } am_hal_host_inst_index_e;
63 
64 //
65 //! Command Errors Types
66 //
67 typedef enum
68 {
69     AM_HAL_CMD_ERR_NONE,
70     AM_HAL_CMD_ERR_INHIBIT,
71     AM_HAL_CMD_ERR_TIMEOUT,
72     AM_HAL_CMD_ERR_INDEX,
73     AM_HAL_CMD_ERR_CRC,
74     AM_HAL_CMD_ERR_ENDBIT,
75     AM_HAL_CMD_ERR_NO_RESPONSE,
76 } am_hal_card_cmd_err_e;
77 
78 //
79 //! Data Errors Types
80 //
81 typedef enum
82 {
83     AM_HAL_DATA_ERR_NONE,
84     AM_HAL_DATA_ERR_ADMAERROR,
85     AM_HAL_DATA_ERR_DATACRCERROR,
86     AM_HAL_DATA_ERR_DATATIMEOUTERROR,
87     AM_HAL_DATA_ERR_DATAENDBITERROR,
88     AM_HAL_DATA_ERR_TIMEOUT,
89 } am_hal_card_data_err_e;
90 
91 //
92 //! Data Direction
93 //
94 typedef enum
95 {
96     AM_HAL_DATA_DIR_READ,
97     AM_HAL_DATA_DIR_WRITE,
98 } am_hal_data_dir_e;
99 
100 //
101 //! SDHC bus Voltage
102 //
103 typedef enum
104 {
105     AM_HAL_HOST_BUS_VOLTAGE_1_8,
106     AM_HAL_HOST_BUS_VOLTAGE_3_0,
107     AM_HAL_HOST_BUS_VOLTAGE_3_3,
108 } am_hal_host_bus_voltage_e;
109 
110 //
111 //! SDHC bus width
112 //
113 typedef enum
114 {
115     AM_HAL_HOST_BUS_WIDTH_1 = 1,
116     AM_HAL_HOST_BUS_WIDTH_4 = 4,
117     AM_HAL_HOST_BUS_WIDTH_8 = 8,
118 } am_hal_host_bus_width_e;
119 
120 //
121 //! SDHC bus transfer mode
122 //
123 typedef enum
124 {
125     AM_HAL_HOST_XFER_DEFAULT,
126     AM_HAL_HOST_XFER_PIO,
127     AM_HAL_HOST_XFER_SDMA,
128     AM_HAL_HOST_XFER_ADMA,
129 } am_hal_host_xfer_mode_e;
130 
131 //
132 //! SDHC bus UHS mode
133 //
134 typedef enum
135 {
136     AM_HAL_HOST_UHS_NONE = 0,
137     AM_HAL_HOST_UHS_SDR12 = 0,
138     AM_HAL_HOST_UHS_SDR25 = 1,
139     AM_HAL_HOST_UHS_SDR50 = 2,
140     AM_HAL_HOST_UHS_SDR104 = 3,
141     AM_HAL_HOST_UHS_DDR50 = 4,
142 } am_hal_host_uhs_mode_e;
143 
144 //
145 //! Command Data Struct
146 //
147 typedef struct
148 {
149     am_hal_data_dir_e dir;
150     am_hal_host_xfer_mode_e eXferMode;
151     bool bNotUseDataLine;
152     uint8_t *pui8Buf;
153     uint32_t ui32BlkSize;
154     uint32_t ui32BlkCnt;
155     am_hal_card_data_err_e eDataError;
156 } am_hal_card_cmd_data_t;
157 
158 //
159 //! Command Struct
160 //
161 typedef struct
162 {
163     uint8_t  ui8Idx;
164     uint32_t ui32Arg;
165     uint32_t ui32RespType;
166     bool bCheckBusyCmd;
167     bool bASync;
168     bool bAutoCMD12;
169     bool bAutoCMD23;
170     uint32_t ui32Resp[4];
171     am_hal_card_cmd_err_e eError;
172 } am_hal_card_cmd_t;
173 
174 typedef struct am_hal_card_host_ops am_hal_card_host_ops_t;
175 
176 //
177 //! SDHC Event Type
178 //
179 typedef enum
180 {
181     AM_HAL_EVT_CARD_NOT_PRESENT,
182     AM_HAL_EVT_CARD_PRESENT,
183     AM_HAL_EVT_PIO_DONE,
184     AM_HAL_EVT_SDMA_DONE,
185     AM_HAL_EVT_XFER_COMPLETE,
186     AM_HAL_EVT_CMD_ERR,
187     AM_HAL_EVT_DAT_ERR,
188 } am_hal_host_evt_type_e;
189 
190 //
191 //! SDHC Host Event Struct
192 //
193 typedef struct
194 {
195     am_hal_host_evt_type_e eType;
196     uint32_t ui32BlkCnt;
197     void *pCtx;
198 } am_hal_host_evt_t;
199 
200 typedef void (*am_hal_host_event_cb_t)(am_hal_host_evt_t *pEvt);
201 
202 //
203 //! SDHC Host Struct
204 //
205 typedef struct am_hal_card_host
206 {
207     void *pHandle;
208     uint32_t ui32Module;
209     bool bCardInSlot;
210     bool bInited;
211     am_hal_host_xfer_mode_e eXferMode;
212     am_hal_host_bus_width_e eBusWidth;
213     am_hal_host_bus_voltage_e eBusVoltage;
214     am_hal_host_uhs_mode_e eUHSMode;
215     uint32_t ui32MaxADMA2BlkNums;
216     uint32_t ui32Clock;
217     uint8_t  ui8Version;
218     uint32_t ui32MaxClock;
219     uint32_t ui32MinClock;
220     uint32_t ui32OCRAvail;
221     am_hal_card_cmd_t AsyncCmd;
222     am_hal_card_cmd_data_t AsyncCmdData;
223     am_hal_card_host_ops_t *ops;
224     am_hal_host_event_cb_t pfunEvtCallback;
225 } am_hal_card_host_t;
226 
227 //
228 //! SDHC Config
229 //
230 typedef struct am_hal_card_cfg_t
231 {
232     uint32_t ui32Clock;
233     am_hal_host_bus_width_e eBusWidth;
234     am_hal_host_bus_voltage_e eIoVoltage;
235     am_hal_host_uhs_mode_e eUHSMode;
236 } am_hal_card_cfg_t;
237 
238 //
239 //! SDHC Host Operations
240 //
241 struct am_hal_card_host_ops
242 {
243     uint32_t (*init)(am_hal_card_host_t *pHost);
244     uint32_t (*deinit)(void *pHandle);
245     uint32_t (*pwr_ctrl)(void *pHandle, bool bOnOff);
246     uint32_t (*execute_cmd)(void *pHandle, am_hal_card_cmd_t *pCmd, am_hal_card_cmd_data_t *pData);
247     uint32_t (*set_bus_voltage)(void *pHandle, am_hal_host_bus_voltage_e eBusVoltage);
248     uint32_t (*set_bus_width)(void *pHandle, am_hal_host_bus_width_e eBusWidth);
249     uint32_t (*set_bus_clock)(void *pHandle, uint32_t ui32Clock);
250     uint32_t (*set_uhs_mode)(void *pHandle, am_hal_host_uhs_mode_e eUHSMode);
251     void (*set_txrx_delay)(void *pHandle, uint8_t ui8TxRxDelays[2]);
252     bool (*get_cd)(void *pHandle);
253     uint32_t (*card_busy)(void *pHandle, uint32_t ui32TimeoutMS);
254 };
255 
256 //*****************************************************************************
257 //
258 //! @brief Get the card host instance function
259 //!
260 //! @param eIndex       - index to the underlying card host instance.
261 //! @param bReInit      - flag that controling the reinitialization of the card host.
262 //!
263 //! This function will find a card host instance and trying to initialize it. if
264 //! card host's initialization succeeds, return a pointer to the instance. otherwise
265 //! a NULL pointer is returned.
266 //!
267 //! @return status      - NULL or a pointer to the card host instance.
268 //
269 //*****************************************************************************
270 extern am_hal_card_host_t *am_hal_get_card_host(am_hal_host_inst_index_e eIndex, bool bReInit);
271 
272 //*****************************************************************************
273 //
274 //! @brief set the card host the transfer mode
275 //!
276 //! @param pHost       - a pointer to the card host instance
277 //! @param eXferMode   - the default transfer mode, like PIO, SDMA or ADMA.
278 //!
279 //! This function sets the default transfer mode like PIO, SDMA or ADMA.
280 //
281 //*****************************************************************************
282 extern void am_hal_card_host_set_xfer_mode(am_hal_card_host_t *pHost, am_hal_host_xfer_mode_e eXferMode);
283 
284 //*****************************************************************************
285 //
286 //! @brief set the card host the TX/RX delay if card host has this feature
287 //!
288 //! @param pHost         - a pointer to the card host instance
289 //! @param ui8TxRxDelays - the TX/RX setting from the 'am_hal_card_emmc_calibrate'
290 //!
291 //! This function sets the TX/RX delay setting if card host card host has this feature
292 //
293 //*****************************************************************************
294 extern void am_hal_card_host_set_txrx_delay(am_hal_card_host_t *pHost, uint8_t ui8TxRxDelays[2]);
295 
296 #ifdef __cplusplus
297 }
298 #endif
299 
300 #endif // AM_HAL_CARD_HOST_H
301 
302 //*****************************************************************************
303 //
304 // End Doxygen group.
305 //! @}
306 //
307 //*****************************************************************************
308 
309