px-fwlib 0.10.0
Cross-platform embedded library and documentation for 8/16/32-bit microcontrollers generated with Doxygen 1.9.2
px_sd.h
1#ifndef __PX_SD_H__
2#define __PX_SD_H__
3/* =============================================================================
4 ____ ___ ____ ___ _ _ ___ __ __ ___ __ __ TM
5 | _ \ |_ _| / ___| / _ \ | \ | | / _ \ | \/ | |_ _| \ \/ /
6 | |_) | | | | | | | | | | \| | | | | | | |\/| | | | \ /
7 | __/ | | | |___ | |_| | | |\ | | |_| | | | | | | | / \
8 |_| |___| \____| \___/ |_| \_| \___/ |_| |_| |___| /_/\_\
9
10 Copyright (c) 2013 Pieter Conradie <https://piconomix.com>
11
12 License: MIT
13 https://github.com/piconomix/px-fwlib/blob/master/LICENSE.md
14
15 Title: px_sd.h : SD Card Driver
16 Author(s): Pieter Conradie
17 Creation Date: 2013-06-21
18
19============================================================================= */
20/**
21 * @ingroup DEVICES_MEM
22 * @defgroup PX_SD px_sd.h : SD Card Driver
23 *
24 * Driver that communicates with an SD (Secure Digital) Card using SPI.
25 *
26 * File(s):
27 * - devices/mem/inc/px_sd.h
28 * - devices/mem/src/px_sd_spi.c
29 *
30 * Reference:
31 * - 1. [SD Specifications Part 1 Physical Layer Simplified Specification 4.10](https://www.sdcard.org/downloads/pls/simplified_specs)
32 * - 2. [ChaN's How to Use MMC/SDC](http://elm-chan.org/docs/mmc/mmc_e.html)
33 * - 3. [Maxim - SD Media Format Expands the MAXQ2000's Space for Nonvolatile Data Storage](http://www.maximintegrated.com/app-notes/index.mvp/id/3969)
34 *
35 * @{
36 */
37
38/* _____PROJECT INCLUDES_____________________________________________________ */
39#include "px_defs.h"
40#include "px_spi.h"
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45/* __DEFINITIONS ____________________________________________________________ */
46/// Maximum SPI Clock rate
47#define PX_SD_MAX_SPI_CLOCK_HZ 25000000ul
48/// SPI Clock / Data phase
49#define PX_SD_SPI_MODE PX_SPI_MODE0
50/// SPI Data order
51#define PX_SD_SPI_DATA_ORDER PX_SPI_DATA_ORDER_MSB
52/// SPI Master Out dummy byte
53#define PX_SD_SPI_MO_DUMMY_BYTE 0xff
54
55/// Size of each data block
56#define PX_SD_BLOCK_SIZE 512ul
57
58/* _____TYPE DEFINITIONS_____________________________________________________ */
59typedef enum
60{
61 PX_SD_CARD_TYPE_INVALID = 0,
62 PX_SD_CARD_TYPE_VER_1_SD = 1,
63 PX_SD_CARD_TYPE_VER_2_SCSD = 2,
64 PX_SD_CARD_TYPE_VER_2_HCSD_XCSD = 3,
65} px_sd_card_type_t;
66
67/// CID - Card ID register; Ref 1. Paragraph "5.2 CID Register", page 113
68typedef struct PX_ATTR_PACKED
69{
70 uint8_t mid; ///< Manufacturer ID
71 char oid[2]; ///< OEM/Application ID [2 ASCII chars]
72 char pnm[5]; ///< Product name [5 ASCII chars]
73 uint8_t prv; ///< BCD Product revision [Major.Minor]
74 uint32_t psn; ///< Product serial number
75 uint8_t year_hi : 4; ///< Manufacturing date [xYYM]
76 uint8_t res1 : 4;
77 uint8_t year_lo : 4; ///< Manufacturing date [xYYM]
78 uint8_t month : 4; ///< Manufacturing date [xYYM]
79 uint8_t crc7_end_bit;
81
82/// CSD - Card Specific Data register; Paragraph "5.3 CSD Register", page 114
83typedef struct PX_ATTR_PACKED
84{
85 // Byte 0
86 uint8_t reserved1 : 6;
87 uint8_t csd_structure : 2; ///< CSD structure version 1.0 or 2.0
88 // Byte 1
89 uint8_t taac; ///< data read access-time-1
90 // Byte 2
91 uint8_t nsac; ///< data read access-time-2 in CLK cycles (NSAC*100)
92 // Byte 3
93 uint8_t tran_speed; ///< max. data transfer rate
94 // Byte 4
95 uint8_t ccc_hi; ///< card command classes
96 // Byte 5
97 uint8_t read_bl_len : 4; ///< max. read data block length
98 uint8_t ccc_lo : 4; ///< card command classes
99
100 union
101 {
102 struct
103 {
104 // Byte 6
105 uint8_t c_size_hi : 2; ///< device size
106 uint8_t reserved2 : 2;
107 uint8_t dsr_imp : 1; ///< DSR implemented
108 uint8_t read_blk_misalign : 1; ///< read block misalignment
109 uint8_t write_blk_misalign : 1; ///< write block misalignment
110 uint8_t read_bl_partial : 1; ///< partial blocks for read allowed
111 // Byte 7
112 uint8_t c_size_mid; ///< device size
113 // Byte 8
114 uint8_t vdd_r_curr_max : 3; ///< max. read current at VDD max
115 uint8_t vdd_r_curr_min : 3; ///< max. read current at VDD min
116 uint8_t c_size_lo : 2; ///< device size
117 // Byte 9
118 uint8_t c_size_mult_hi : 2; ///< device size multiplier
119 uint8_t vdd_w_cur_max : 3; ///< max. write current at VDD max
120 uint8_t vdd_w_curr_min : 3; ///< max. write current at VDD min
121 // Byte 10
122 uint8_t sector_size_hi : 6; ///< erase sector size
123 uint8_t erase_blk_en : 1; ///< erase single block enable
124 uint8_t c_size_mult_lo : 1; ///< device size multiplier
125 // Byte 11
126 uint8_t wp_grp_size : 7; ///< write protect group size
127 uint8_t sector_size_lo : 1; ///< erase sector size
128 } csd_1_0;
129
130 struct
131 {
132 // Byte 6
133 uint8_t reserved2 : 4;
134 uint8_t dsr_imp : 1; ///< DSR implemented
135 uint8_t read_blk_misalign : 1; ///< read block misalignment
136 uint8_t write_blk_misalign : 1; ///< write block misalignment
137 uint8_t read_bl_partial : 1; ///< partial blocks for read allowed
138 // Byte 7
139 uint8_t c_size_hi : 6; ///< device size
140 uint8_t reserved3 : 2;
141 // Byte 8
142 uint8_t c_size_mid : 8; ///< device size
143 // Byte 9
144 uint8_t c_size_lo : 8; ///< device size
145 // Byte 10
146 uint8_t sector_size_hi : 6; ///< erase sector size
147 uint8_t erase_blk_en : 1; ///< erase single block enable
148 uint8_t reserved4 : 1;
149 // Byte 11
150 uint8_t wp_grp_size : 7; ///< write protect group size
151 uint8_t sector_size_lo : 1; ///< erase sector size
152 } csd_2_0;
153 } ver;
154
155 // Byte 12
156 uint8_t write_bl_len_hi : 2; ///< max. write data block length
157 uint8_t r2w_factor : 3; ///< write speed factor
158 uint8_t reserved3 : 2;
159 uint8_t wp_grp_enable : 1; ///< write protect group enable
160 // Byte 13
161 uint8_t reserved4 : 5;
162 uint8_t write_partial : 1; ///< partial blocks for write allowed
163 uint8_t write_bl_len_low : 2; ///< max. write data block length
164 // Byte 14
165 uint8_t reserved5: 2;
166 uint8_t file_format : 2; ///< File format
167 uint8_t tmp_write_protect : 1; ///< temporary write protection
168 uint8_t perm_write_protect : 1; ///< permanent write protection
169 uint8_t copy : 1; ///< copy flag
170 uint8_t file_format_grp : 1; ///< File format
171 // Byte 15
172 uint8_t crc7_end_bit; ///< CRC
174
175/* _____GLOBAL VARIABLES_____________________________________________________ */
176
177/* _____GLOBAL FUNCTION DECLARATIONS_________________________________________ */
178/**
179 * Initialise driver.
180 *
181 * @param handle SPI handle to use for SPI slave device
182 */
183void px_sd_init(px_spi_handle_t * handle);
184
185/**
186 * Detect and reset SD card.
187 *
188 * @retval true SD card detected and reset to known state
189 * @retval false SD card not detected or not supported
190 */
191bool px_sd_reset(void);
192
193/**
194 * Read Card ID Register.
195 *
196 * @param cid Structure to store data
197 *
198 * @retval true Card ID register succesfully read
199 * @retval false Error while trying to read Card ID register
200 */
201bool px_sd_rd_cid(px_sd_cid_t * cid);
202
203/**
204 * Read Card Specific Data.
205 *
206 * @param csd Structure to store data
207 *
208 * @retval true Card Specific Data succesfully read
209 * @retval false Error while trying to read Card Specific Data
210 */
211bool px_sd_rd_csd(px_sd_csd_t * csd);
212
213/**
214 * Read Card Status.
215 *
216 * @param status Variable to store card status in
217 *
218 * @retval true Card Status succesfully read
219 * @retval false Error while trying to read Card Status
220 */
221bool px_sd_get_status(uint16_t * status);
222
223/**
224 * Extract and calculate card capacity from Card Specific Data (CSD).
225 *
226 * @param csd Card Specific Data
227 *
228 * @return uint32_t Card capacity in number of blocks (see #PX_SD_BLOCK_SIZE)
229 */
230uint32_t px_sd_get_capacity_in_blocks(const px_sd_csd_t * csd);
231
232/**
233 * Read a data block from the SD card.
234 *
235 * The data block size is #PX_SD_BLOCK_SIZE and the specified array must be big
236 * enough to accept the whole data block.
237 *
238 * @param data Pointer to array where data block must be stored
239 * @param block_adr Address of block to read.
240 *
241 * @retval true Data block succcesfully read
242 * @retval false Error while trying to read data block
243 */
244bool px_sd_rd_block(uint8_t * data, uint32_t block_adr);
245
246/**
247 * Read a number of data blocks from the SD card.
248 *
249 * The data block size is #PX_SD_BLOCK_SIZE and the specified array must be big
250 * enough to accept (nr_of_blocks x PX_SD_BLOCK_SIZE).
251 *
252 * @param data Pointer to array where data blocks must be stored
253 * @param block_adr Address of start block to read
254 * @param nr_of_blocks Number of blocks to read
255 *
256 * @return uint8_t Number of blocks succesfully read
257 */
258uint8_t px_sd_rd_blocks(uint8_t * data, uint32_t block_adr, uint8_t nr_of_blocks);
259
260/**
261 * Write a data block to the SD card.
262 *
263 * The data block size is #PX_SD_BLOCK_SIZE and the specified array must contain
264 * the whole data block. Poll px_sd_wait_write_finished() to find out when write
265 * operation has finished, e.g. before powering down SD card.
266 *
267 * @param data Pointer to array containing data block content to be written
268 * @param block_adr Address of block to write.
269 *
270 * @retval true Data block succcesfully written
271 * @retval false Error while trying to write data block
272 */
273bool px_sd_wr_block(const uint8_t * data, uint32_t block_adr);
274
275/**
276 * Write a number of data blocks to the SD card.
277 *
278 * The data block size is #PX_SD_BLOCK_SIZE and the specified array must contain
279 * (nr_of_blocks x PX_SD_BLOCK_SIZE). Poll px_sd_wait_write_finished() to find out
280 * when write operation has finished, e.g. before powering down SD card.
281 *
282 * @param data Pointer to array containing content to be written
283 * @param block_adr Address of start block to write.
284 * @param nr_of_blocks Number of blocks to write
285 *
286 * @return uint8_t Number of blocks succesfully written
287 */
288uint8_t px_sd_wr_blocks(const uint8_t * data, uint32_t block_adr, uint8_t nr_of_blocks);
289
290/**
291 * Wait up to 500 ms for write block transaction to finish.
292 *
293 * @retval true Write operation finished
294 * @retval false Timed-out waiting for SD card to be ready
295 */
297
298/* _____MACROS_______________________________________________________________ */
299
300#ifdef __cplusplus
301}
302#endif
303
304/// @}
305#endif
uint8_t year_hi
Manufacturing date [xYYM].
Definition: px_sd.h:75
uint8_t mid
Manufacturer ID.
Definition: px_sd.h:70
uint8_t r2w_factor
write speed factor
Definition: px_sd.h:157
uint8_t tran_speed
max. data transfer rate
Definition: px_sd.h:93
uint8_t prv
BCD Product revision [Major.Minor].
Definition: px_sd.h:73
uint8_t month
Manufacturing date [xYYM].
Definition: px_sd.h:78
uint8_t wp_grp_enable
write protect group enable
Definition: px_sd.h:159
uint8_t ccc_hi
card command classes
Definition: px_sd.h:95
uint8_t taac
data read access-time-1
Definition: px_sd.h:89
uint8_t write_partial
partial blocks for write allowed
Definition: px_sd.h:162
uint8_t csd_structure
CSD structure version 1.0 or 2.0.
Definition: px_sd.h:87
uint8_t write_bl_len_hi
max. write data block length
Definition: px_sd.h:156
uint8_t write_bl_len_low
max. write data block length
Definition: px_sd.h:163
uint8_t read_bl_len
max. read data block length
Definition: px_sd.h:97
uint8_t crc7_end_bit
CRC.
Definition: px_sd.h:172
uint32_t psn
Product serial number
Definition: px_sd.h:74
uint8_t year_lo
Manufacturing date [xYYM].
Definition: px_sd.h:77
uint8_t nsac
data read access-time-2 in CLK cycles (NSAC*100)
Definition: px_sd.h:91
uint8_t perm_write_protect
permanent write protection
Definition: px_sd.h:168
uint8_t file_format
File format.
Definition: px_sd.h:166
uint8_t tmp_write_protect
temporary write protection
Definition: px_sd.h:167
uint8_t ccc_lo
card command classes
Definition: px_sd.h:98
uint8_t file_format_grp
File format.
Definition: px_sd.h:170
uint8_t copy
copy flag
Definition: px_sd.h:169
bool px_sd_reset(void)
Detect and reset SD card.
Definition: px_sd.c:331
bool px_sd_rd_block(uint8_t *data, uint32_t block_adr)
Read a data block from the SD card.
Definition: px_sd.c:652
uint8_t px_sd_wr_blocks(const uint8_t *data, uint32_t block_adr, uint8_t nr_of_blocks)
Write a number of data blocks to the SD card.
Definition: px_sd.c:779
bool px_sd_wait_wr_is_finished(void)
Wait up to 500 ms for write block transaction to finish.
Definition: px_sd.c:858
void px_sd_init(px_spi_handle_t *handle)
Initialise driver.
Definition: px_sd.c:325
bool px_sd_rd_cid(px_sd_cid_t *cid)
Read Card ID Register.
Definition: px_sd.c:514
bool px_sd_wr_block(const uint8_t *data, uint32_t block_adr)
Write a data block to the SD card.
Definition: px_sd.c:743
uint32_t px_sd_get_capacity_in_blocks(const px_sd_csd_t *csd)
Extract and calculate card capacity from Card Specific Data (CSD).
Definition: px_sd.c:593
bool px_sd_get_status(uint16_t *status)
Read Card Status.
Definition: px_sd.c:571
bool px_sd_rd_csd(px_sd_csd_t *csd)
Read Card Specific Data.
Definition: px_sd.c:539
uint8_t px_sd_rd_blocks(uint8_t *data, uint32_t block_adr, uint8_t nr_of_blocks)
Read a number of data blocks from the SD card.
Definition: px_sd.c:685
CID - Card ID register; Ref 1. Paragraph "5.2 CID Register", page 113.
Definition: px_sd.h:69
CSD - Card Specific Data register; Paragraph "5.3 CSD Register", page 114.
Definition: px_sd.h:84
Define SPI handle.
Definition: px_spi.h:126