1 /*
2  * Copyright (c) 2016-2019, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*!***************************************************************************
34  *  @file       SD.h
35  *  @brief      Secure Digital (SD) Driver
36  *
37  *  @anchor ti_drivers_SD_Overview
38  *  # Overview
39  *
40  *  The SD driver is designed to serve as an interface to perform basic
41  *  transfers directly to the SD card.
42  *
43  *  <hr>
44  *  @anchor ti_drivers_SD_Usage
45  *  # Usage
46  *  This section will cover driver usage.
47  *
48  *  @anchor ti_drivers_SD_Synopsis
49  *  ## Synopsis
50  *  @anchor ti_drivers_SD_Synopsis_Code
51  *  @code
52  *  SD_Handle handle;
53  *  uint16_t status;
54  *
55  *  SD_init();
56  *
57  *  // Open SD and initialize card
58  *  handle = SD_open(CONFIG_SD0, NULL);
59  *  status = SD_initialize(handle);
60  *  if (handle == NULL || status != SD_STATUS_SUCCESS) {
61  *      //Error opening SD driver
62  *      while (1);
63  *  }
64  *
65  *  // Write and read back the first sector
66  *  status = SD_write(handle, sendBuffer, 0, 1);
67  *  if (status == SD_STATUS_SUCCESS) {
68  *      status = SD_read(handle, readBuffer, 0 , 1);
69  *  }
70  *
71  *  SD_close(handle);
72  *  @endcode
73  *
74  *  @anchor ti_drivers_SD_Examples
75  *  # Examples
76  *  - @ref ti_drivers_SD_Synopsis "Overview"
77  *  - @ref ti_drivers_SD_Example_getCardSpace "Get SD card size"
78  *
79  *  Get total capacity of an SD card:
80  *  @anchor ti_drivers_SD_Example_getCardSpace
81  *  @code
82  *  SD_Handle handle;
83  *  Display_Handle display;
84  *  uint_fast32_t sectorSize, sectorCount;
85  *
86  *  // Init, open, etc
87  *  ...
88  *
89  *  sectorSize = SD_getSectorSize(handle);
90  *  sectorCount = SD_getNumSectors(handle);
91  *
92  *  Display_printf(display, 0, 0,"SD card total capacity is %lu bytes.",
93  *                 sectorSize * sectorCount);
94  *  @endcode
95  *
96  *  <hr>
97  *  @anchor ti_drivers_SD_Configuration
98  *  # Configuration
99  *  Refer to the @ref driver_configuration "Driver's Configuration"
100  *  section for driver configuration information.
101  *
102  *  <hr>
103  ******************************************************************************
104  */
105 
106 #ifndef ti_drivers_SD__include
107 #define ti_drivers_SD__include
108 
109 #include <stdint.h>
110 
111 #ifdef __cplusplus
112 extern "C" {
113 #endif
114 
115 /**
116  *  @defgroup SD_CONTROL SD_control command and status codes
117  *  @{
118  */
119 
120 /*!
121  * Common SD_control() command code reservation offset.
122  * SD driver implementations should offset command codes with
123  * SD_CMD_RESERVED growing positively.
124  *
125  * Example implementation specific command codes:
126  * @code
127  * #define SDXYZ_CMD_COMMAND0    (SD_CMD_RESERVED + 0)
128  * #define SDXYZ_CMD_COMMAND1    (SD_CMD_RESERVED + 1)
129  * @endcode
130  */
131 #define SD_CMD_RESERVED    (32)
132 
133 /*!
134  * Common SD_control status code reservation offset.
135  * SD driver implementations should offset status codes with
136  * SD_STATUS_RESERVED growing negatively.
137  *
138  * Example implementation specific status codes:
139  * @code
140  * #define SDXYZ_STATUS_ERROR0    (SD_STATUS_RESERVED - 0)
141  * #define SDXYZ_STATUS_ERROR1    (SD_STATUS_RESERVED - 1)
142  * #define SDXYZ_STATUS_ERROR2    (SD_STATUS_RESERVED - 2)
143  * @endcode
144  */
145 #define SD_STATUS_RESERVED    (-32)
146 
147 /**
148  *  @defgroup SD_STATUS Status Codes
149  *  SD_STATUS_* macros are general status codes returned by SD_control()
150  *  @{
151  *  @ingroup SD_CONTROL
152  */
153 
154 /*!
155  * @brief Successful status code returned by SD_control().
156  *
157  * SD_control() returns SD_STATUS_SUCCESS if the control code was executed
158  * successfully.
159  */
160 #define SD_STATUS_SUCCESS    (0)
161 
162 /*!
163  * @brief Generic error status code returned by SD_control().
164  *
165  * SD_control() returns SD_STATUS_ERROR if the control code
166  * was not executed successfully.
167  */
168 #define SD_STATUS_ERROR    (-1)
169 
170 /*!
171  * @brief   An error status code returned by SD_control() for
172  * undefined command codes.
173  *
174  * SD_control() returns SD_STATUS_UNDEFINEDCMD if the
175  * control code is not recognized by the driver implementation.
176  */
177 #define SD_STATUS_UNDEFINEDCMD    (-2)
178 /** @}*/
179 
180 /**
181  *  @defgroup SD_CMD Command Codes
182  *  SD_CMD_* macros are general command codes for SD_control(). Not all SD
183  *  driver implementations support these command codes.
184  *  @{
185  *  @ingroup SD_CONTROL
186  */
187 
188 /* Add SD_CMD_<commands> here */
189 
190 /** @}*/
191 
192 /** @}*/
193 
194 /*!
195  *  @brief  SD Card type inserted
196  */
197 typedef enum {
198     SD_NOCARD = 0, /*!< Unrecognized Card */
199     SD_MMC = 1,    /*!< Multi-media Memory Card (MMC) */
200     SD_SDSC = 2,   /*!< Standard SDCard (SDSC) */
201     SD_SDHC = 3    /*!< High Capacity SDCard (SDHC) */
202 } SD_CardType;
203 
204 /*!
205  *  @brief      A handle that is returned from a SD_open() call.
206  */
207 typedef struct SD_Config_ *SD_Handle;
208 
209 /*!
210  *  @brief SD Parameters
211  *
212  *  SD Parameters are used to with the SD_open() call.
213  *  Default values for these parameters are set using SD_Params_init().
214  *
215  *  @sa SD_Params_init()
216  */
217 
218 /* SD Parameters */
219 typedef struct {
220     void   *custom;  /*!< Custom argument used by driver implementation */
221 } SD_Params;
222 
223 /*!
224  *  @brief A function pointer to a driver specific implementation of
225  *         SD_CloseFxn().
226  */
227 typedef void (*SD_CloseFxn) (SD_Handle handle);
228 
229 /*!
230  *  @brief A function pointer to a driver specific implementation of
231  *         SD_controlFxn().
232  */
233 typedef int_fast16_t (*SD_ControlFxn) (SD_Handle handle,
234     uint_fast16_t cmd, void *arg);
235 
236 /*!
237  *  @brief A function pointer to a driver specific implementation of
238  *         SD_getNumSectorsFxn().
239  */
240 typedef uint_fast32_t (*SD_getNumSectorsFxn) (SD_Handle handle);
241 
242 /*!
243  *  @brief A function pointer to a driver specific implementation of
244  *         SD_getSectorSizeFxn().
245  */
246 typedef uint_fast32_t (*SD_getSectorSizeFxn) (SD_Handle handle);
247 
248 /*!
249  *  @brief A function pointer to a driver specific implementation of
250  *         SD_InitFxn().
251  */
252 typedef void (*SD_InitFxn) (SD_Handle handle);
253 
254 /*!
255  *  @brief A function pointer to a driver specific implementation of
256  *         SD_initializeFxn().
257  */
258 typedef int_fast16_t (*SD_InitializeFxn) (SD_Handle handle);
259 
260 /*!
261  *  @brief A function pointer to a driver specific implementation of
262  *         SD_OpenFxn().
263  */
264 typedef SD_Handle (*SD_OpenFxn) (SD_Handle handle, SD_Params *params);
265 
266 /*!
267  *  @brief A function pointer to a driver specific implementation of
268  *         SD_readFxn().
269  */
270 typedef int_fast16_t (*SD_ReadFxn) (SD_Handle handle, void *buf,
271     int_fast32_t sector, uint_fast32_t secCount);
272 
273 /*!
274  *  @brief A function pointer to a driver specific implementation of
275  *         SD_writeFxn().
276  */
277 typedef int_fast16_t (*SD_WriteFxn) (SD_Handle handle, const void *buf,
278     int_fast32_t sector, uint_fast32_t secCount);
279 
280 /*!
281  *  @brief The definition of a SD function table that contains the
282  *         required set of functions to control a specific SD driver
283  *         implementation.
284  */
285 typedef struct {
286     /*! Function to close the specified peripheral */
287     SD_CloseFxn             closeFxn;
288     /*! Function to implementation specific control function */
289     SD_ControlFxn           controlFxn;
290     /*! Function to return the total number of sectors on the SD card */
291     SD_getNumSectorsFxn     getNumSectorsFxn;
292     /*! Function to return the sector size used to address the SD card */
293     SD_getSectorSizeFxn     getSectorSizeFxn;
294     /*! Function to initialize the given data object */
295     SD_InitFxn              initFxn;
296     /*! Function to initialize the SD card */
297     SD_InitializeFxn        initializeFxn;
298     /*! Function to open the specified peripheral */
299     SD_OpenFxn              openFxn;
300     /*! Function to read from the SD card */
301     SD_ReadFxn              readFxn;
302     /*! Function to write to the SD card */
303     SD_WriteFxn             writeFxn;
304 } SD_FxnTable;
305 
306 /*!
307  *  @brief SD Global configuration
308  *
309  *  The SD_Config structure contains a set of pointers used
310  *  to characterize the SD driver implementation.
311  *
312  *  This structure needs to be defined before calling SD_init() and it must
313  *  not be changed thereafter.
314  *
315  *  @sa SD_init()
316  */
317 typedef struct SD_Config_ {
318     /*! Pointer to a table of driver-specific implementations of SD APIs */
319     SD_FxnTable const    *fxnTablePtr;
320 
321     /*! Pointer to a driver specific data object */
322     void                 *object;
323 
324     /*! Pointer to a driver specific hardware attributes structure */
325     void const           *hwAttrs;
326 } SD_Config;
327 
328 /*!
329  *  @brief Function to close a SD peripheral specified by the SD handle.
330  *
331  *  @pre SD_open() had to be called first.
332  *
333  *  @param handle A #SD_Handle returned from SD_open()
334  *
335  *  @sa SD_open()
336  */
337 extern void SD_close(SD_Handle handle);
338 
339 /*!
340  *  @brief  Function performs implementation specific features on a given
341  *          #SD_Handle.
342  *
343  *  Commands for SD_control can originate from SD.h or from implementation
344  *  specific SD*.h files.
345  *  While commands from SD.h are API portable across driver implementations,
346  *  not all implementations may support all these commands.
347  *  Conversely, commands from driver implementation specific SD*.h files add
348  *  unique driver capabilities but are not API portable across all SD driver
349  *  implementations.
350  *
351  *  Commands supported by SD.h follow a SD*_CMD naming
352  *  convention.
353  *
354  *  Commands supported by SD*.h follow a SD*_CMD naming
355  *  convention.
356  *  Each control command defines arg differently. The types of arg are
357  *  documented with each command.
358  *
359  *  See @ref SD_CMD "SD_control command codes" for command codes.
360  *
361  *  See @ref SD_STATUS "SD_control return status codes" for status codes.
362  *
363  *  @pre SD_open() has to be called first.
364  *
365  *  @param handle A #SD_Handle returned from SD_open().
366  *
367  *  @param cmd SD.h or SD*.h commands.
368  *
369  *  @param arg An optional R/W (read/write) command argument
370  *              accompanied with cmd.
371  *
372  *  @return Implementation specific return codes. Negative values indicate
373  *          unsuccessful operations.
374  *
375  *  @sa SD_open()
376  */
377 extern int_fast16_t SD_control(SD_Handle handle, uint_fast16_t cmd, void *arg);
378 
379 /*!
380  *  @brief A function pointer to a driver specific implementation of
381  *         SD_getNumSectors().
382  *         Note: Total Card capacity is the (NumberOfSectors * SectorSize).
383  *
384  *  @pre SD Card has been initialized using SD_initialize().
385  *
386  *  @param  handle A #SD_Handle returned from SD_open().
387  *
388  *  @return The total number of sectors on the SD card,
389  *          or 0 if an error occurred.
390  *
391  *  @sa SD_initialize()
392  */
393 extern uint_fast32_t SD_getNumSectors(SD_Handle handle);
394 
395 /*!
396  *  @brief Function to obtain the sector size used to access the SD card.
397  *
398  *  @pre SD Card has been initialized using SD_initialize().
399  *
400  *  @param handle A #SD_Handle returned from SD_open().
401  *
402  *  @return The sector size set for use during SD card read/write operations.
403  *
404  *  @sa SD_initialize()
405  */
406 extern uint_fast32_t SD_getSectorSize(SD_Handle handle);
407 
408 /*!
409  *  @brief This function initializes the SD driver.
410  *
411  *  @pre The SD_config[] array must exist and be persistent before this
412  *       function can be called. This function must also be called before
413  *       any other SD driver APIs. This function call does not modify any
414  *       peripheral registers.
415  */
416 extern void SD_init(void);
417 
418 /*!
419  *  @brief Function to initialize the #SD_Params struct to its defaults.
420  *
421  *  @param params A pointer to #SD_Params structure for initialization.
422  */
423 extern void SD_Params_init(SD_Params *params);
424 
425  /*!
426  *  @brief  A function pointer to a driver specific implementation of
427  *          SD_initialize().
428  *
429  *  @pre    SD controller has been opened by calling SD_open().
430  *
431  *  @param  handle A #SD_Handle returned from SD_open().
432  *
433  *  @return #SD_STATUS_SUCCESS if no errors occurred during the initialization,
434  *          #SD_STATUS_ERROR otherwise.
435  */
436 extern int_fast16_t SD_initialize(SD_Handle handle);
437 
438 /*!
439  *  @brief A function pointer to a driver specific implementation of
440  *          SD_open().
441  *
442  *  @pre SD controller has been initialized using SD_init().
443  *
444  *  @param index  Logical peripheral number for the SD indexed into
445  *                the SD_config[] table.
446  *
447  *  @param params Pointer to a parameter block, if NULL it will use
448  *                default values. All the fields in this structure are
449  *                RO (read-only).
450  *
451  *  @return A #SD_Handle on success or a NULL on an error or if it has been
452  *          opened already.
453  *
454  *  @sa SD_init()
455  *  @sa SD_close()
456  */
457 extern SD_Handle SD_open(uint_least8_t index, SD_Params *params);
458 
459 /*!
460  *  @brief A function pointer to a driver specific implementation of
461  *          SD_read().
462  *
463  *  @pre SD controller has been opened and initialized by calling SD_open()
464  *       followed by SD_initialize().
465  *
466  *  @param handle A #SD_Handle returned from SD_open().
467  *
468  *  @param buf Pointer to a buffer to read data into.
469  *
470  *  @param sector Starting sector on the disk to read from.
471  *
472  *  @param secCount Number of sectors to be read.
473  *
474  *  @return #SD_STATUS_SUCCESS if no errors occurred during the write,
475  *          #SD_STATUS_ERROR otherwise.
476  *
477  *  @sa SD_initialize()
478  */
479 extern int_fast16_t SD_read(SD_Handle handle, void *buf,
480     int_fast32_t sector, uint_fast32_t secCount);
481 
482 /*!
483  *  @brief A function pointer to a driver specific implementation of
484  *         SD_write().
485  *
486  *  @pre SD controller has been opened and initialized by calling SD_open()
487  *       followed by SD_initialize().
488  *
489  *  @param  handle A #SD_Handle returned from SD_open().
490  *
491  *  @param  buf Pointer to a buffer containing data to write to disk.
492  *
493  *  @param  sector Starting sector on the disk to write to.
494  *
495  *  @param  secCount Number of sectors to be written.
496  *
497  *  @return #SD_STATUS_SUCCESS if no errors occurred during the write,
498  *          #SD_STATUS_ERROR otherwise.
499  *
500  *  @sa     SD_initialize()
501  */
502 extern int_fast16_t SD_write(SD_Handle handle, const void *buf,
503     int_fast32_t sector, uint_fast32_t secCount);
504 
505 #ifdef __cplusplus
506 }
507 #endif
508 
509 #endif /* ti_drivers_SD__include */
510