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 stable-7da8bae71f 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 Controller 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_CMD_ERR_INVALID_RESPONSE,
77 } am_hal_card_cmd_err_e;
78 
79 //
80 //! Data Errors Types
81 //
82 typedef enum
83 {
84     AM_HAL_DATA_ERR_NONE,
85     AM_HAL_DATA_ERR_ADMAERROR,
86     AM_HAL_DATA_ERR_DATACRCERROR,
87     AM_HAL_DATA_ERR_DATATIMEOUTERROR,
88     AM_HAL_DATA_ERR_DATAENDBITERROR,
89     AM_HAL_DATA_ERR_TIMEOUT,
90 } am_hal_card_data_err_e;
91 
92 //
93 //! Data Direction
94 //
95 typedef enum
96 {
97     AM_HAL_DATA_DIR_READ,
98     AM_HAL_DATA_DIR_WRITE,
99 } am_hal_data_dir_e;
100 
101 //
102 //! SDHC bus Voltage
103 //
104 typedef enum
105 {
106     AM_HAL_HOST_BUS_VOLTAGE_1_8,
107     AM_HAL_HOST_BUS_VOLTAGE_3_0,
108     AM_HAL_HOST_BUS_VOLTAGE_3_3,
109 } am_hal_host_bus_voltage_e;
110 
111 //
112 //! SDHC bus width
113 //
114 typedef enum
115 {
116     AM_HAL_HOST_BUS_WIDTH_1 = 1,
117     AM_HAL_HOST_BUS_WIDTH_4 = 4,
118     AM_HAL_HOST_BUS_WIDTH_8 = 8,
119 } am_hal_host_bus_width_e;
120 
121 //
122 //! SDHC bus transfer mode
123 //
124 typedef enum
125 {
126     AM_HAL_HOST_XFER_DEFAULT,
127     AM_HAL_HOST_XFER_PIO,
128     AM_HAL_HOST_XFER_SDMA,
129     AM_HAL_HOST_XFER_ADMA,
130 } am_hal_host_xfer_mode_e;
131 
132 //
133 //! SDHC bus UHS mode
134 //
135 typedef enum
136 {
137     AM_HAL_HOST_UHS_NONE = 0,
138     AM_HAL_HOST_UHS_SDR12 = 0,
139     AM_HAL_HOST_UHS_SDR25 = 1,
140     AM_HAL_HOST_UHS_SDR50 = 2,
141     AM_HAL_HOST_UHS_SDR104 = 3,
142     AM_HAL_HOST_UHS_DDR50 = 4,
143 } am_hal_host_uhs_mode_e;
144 
145 //
146 //! Scatter IO Struct
147 //
148 typedef struct
149 {
150     void     *pIovBase;
151     uint32_t ui32IovLen;
152 } am_hal_card_iovec_t;
153 
154 //
155 //! Command Data Struct
156 //
157 typedef struct
158 {
159     am_hal_data_dir_e dir;
160     am_hal_host_xfer_mode_e eXferMode;
161     bool bNotUseDataLine;
162     uint8_t *pui8Buf;
163     uint32_t ui32BlkSize;
164     uint32_t ui32BlkCnt;
165     uint8_t  ui8IovCnt;
166     am_hal_card_iovec_t *pIov;
167     am_hal_card_data_err_e eDataError;
168 } am_hal_card_cmd_data_t;
169 
170 //
171 //! Command Struct
172 //
173 typedef struct
174 {
175     uint8_t  ui8Idx;
176     uint32_t ui32Arg;
177     uint32_t ui32RespType;
178     bool bCheckBusyCmd;
179     bool bASync;
180     bool bAutoCMD12;
181     bool bAutoCMD23;
182     uint32_t ui32Resp[4];
183     am_hal_card_cmd_err_e eError;
184 } am_hal_card_cmd_t;
185 
186 typedef struct am_hal_card_host_ops am_hal_card_host_ops_t;
187 
188 //
189 //! SDHC Event Type
190 //
191 typedef enum
192 {
193     AM_HAL_EVT_CARD_NOT_PRESENT,
194     AM_HAL_EVT_CARD_PRESENT,
195     AM_HAL_EVT_PIO_DONE,
196     AM_HAL_EVT_SDMA_DONE,
197     AM_HAL_EVT_XFER_COMPLETE,
198     AM_HAL_EVT_CMD_ERR,
199     AM_HAL_EVT_DAT_ERR,
200 } am_hal_host_evt_type_e;
201 
202 //
203 //! SDHC Host Event Struct
204 //
205 typedef struct
206 {
207     am_hal_host_evt_type_e eType;
208     uint32_t ui32BlkCnt;
209     void *pCtx;
210 } am_hal_host_evt_t;
211 
212 typedef void (*am_hal_host_event_cb_t)(am_hal_host_evt_t *pEvt);
213 
214 //
215 //! SDHC Host Struct
216 //
217 typedef struct am_hal_card_host
218 {
219     void *pHandle;
220     uint32_t ui32Module;
221     bool bCardInSlot;
222     bool bInited;
223     am_hal_host_xfer_mode_e eXferMode;
224     am_hal_host_bus_width_e eBusWidth;
225     am_hal_host_bus_voltage_e eBusVoltage;
226     am_hal_host_uhs_mode_e eUHSMode;
227     uint32_t ui32MaxADMA2BlkNums;
228     uint32_t ui32Clock;
229     uint8_t  ui8Version;
230     uint32_t ui32MaxClock;
231     uint32_t ui32MinClock;
232     uint32_t ui32OCRAvail;
233     am_hal_card_cmd_t AsyncCmd;
234     am_hal_card_cmd_data_t AsyncCmdData;
235     am_hal_card_host_ops_t *ops;
236     am_hal_host_event_cb_t pfunEvtCallback;
237 } am_hal_card_host_t;
238 
239 //
240 //! SDHC Config
241 //
242 typedef struct am_hal_card_cfg_t
243 {
244     uint32_t ui32Clock;
245     am_hal_host_bus_width_e eBusWidth;
246     am_hal_host_bus_voltage_e eIoVoltage;
247     am_hal_host_uhs_mode_e eUHSMode;
248 } am_hal_card_cfg_t;
249 
250 //
251 //! SDHC Host Operations
252 //
253 struct am_hal_card_host_ops
254 {
255     uint32_t (*init)(am_hal_card_host_t *pHost);
256     uint32_t (*deinit)(void *pHandle);
257     uint32_t (*pwr_ctrl)(void *pHandle, bool bOnOff);
258     uint32_t (*execute_cmd)(void *pHandle, am_hal_card_cmd_t *pCmd, am_hal_card_cmd_data_t *pData);
259     uint32_t (*set_bus_voltage)(void *pHandle, am_hal_host_bus_voltage_e eBusVoltage);
260     uint32_t (*set_bus_width)(void *pHandle, am_hal_host_bus_width_e eBusWidth);
261     uint32_t (*set_bus_clock)(void *pHandle, uint32_t ui32Clock);
262     uint32_t (*set_uhs_mode)(void *pHandle, am_hal_host_uhs_mode_e eUHSMode);
263     void (*set_txrx_delay)(void *pHandle, uint8_t ui8TxRxDelays[2]);
264     bool (*get_cd)(void *pHandle);
265     bool (*get_wr_protect)(void *pHandle);
266     uint32_t (*card_busy)(void *pHandle, uint32_t ui32TimeoutMS);
267 };
268 
269 //*****************************************************************************
270 //
271 //! @brief Get the card host instance function
272 //!
273 //! @param eIndex       - index to the underlying card host instance.
274 //! @param bReInit      - flag that controling the reinitialization of the card host.
275 //!
276 //! This function will find a card host instance and trying to initialize it. if
277 //! card host's initialization succeeds, return a pointer to the instance. otherwise
278 //! a NULL pointer is returned.
279 //!
280 //! @return status      - NULL or a pointer to the card host instance.
281 //
282 //*****************************************************************************
283 extern am_hal_card_host_t *am_hal_get_card_host(am_hal_host_inst_index_e eIndex, bool bReInit);
284 
285 //*****************************************************************************
286 //
287 //! @brief set the card host the transfer mode
288 //!
289 //! @param pHost       - a pointer to the card host instance
290 //! @param eXferMode   - the default transfer mode, like PIO, SDMA or ADMA.
291 //!
292 //! This function sets the default transfer mode like PIO, SDMA or ADMA.
293 //
294 //*****************************************************************************
295 extern void am_hal_card_host_set_xfer_mode(am_hal_card_host_t *pHost, am_hal_host_xfer_mode_e eXferMode);
296 
297 //*****************************************************************************
298 //
299 //! @brief set the card host the TX/RX delay if card host has this feature
300 //!
301 //! @param pHost         - a pointer to the card host instance
302 //! @param ui8TxRxDelays - the TX/RX setting from the 'am_hal_card_emmc_calibrate'
303 //!
304 //! This function sets the TX/RX delay setting if card host card host has this feature
305 //
306 //*****************************************************************************
307 extern void am_hal_card_host_set_txrx_delay(am_hal_card_host_t *pHost, uint8_t ui8TxRxDelays[2]);
308 
309 #ifdef __cplusplus
310 }
311 #endif
312 
313 #endif // AM_HAL_CARD_HOST_H
314 
315 //*****************************************************************************
316 //
317 // End Doxygen group.
318 //! @}
319 //
320 //*****************************************************************************
321 
322