Mistake on this page?
Report an issue in GitHub or email us
SDBlockDevice.h
1 /* mbed Microcontroller Library
2  * Copyright (c) 2006-2013 ARM Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef MBED_SD_BLOCK_DEVICE_H
18 #define MBED_SD_BLOCK_DEVICE_H
19 
20 /* If the target has no SPI support, then SD Card is not supported. */
21 #if DEVICE_SPI
22 
23 #include "BlockDevice.h"
24 #include "drivers/SPI.h"
25 #include "drivers/Timer.h"
26 #include "drivers/MbedCRC.h"
27 #include "drivers/DigitalOut.h"
28 #include "platform/platform.h"
29 #include "platform/PlatformMutex.h"
30 
31 /** SDBlockDevice class
32  *
33  * Access an SD Card using SPI bus
34  */
36 public:
37  /** Creates an SDBlockDevice on a SPI bus specified by pins
38  *
39  * @param mosi SPI master out, slave in pin
40  * @param miso SPI master in, slave out pin
41  * @param sclk SPI clock pin
42  * @param cs SPI chip select pin
43  * @param hz Clock speed of the SPI bus (defaults to 1MHz)
44  * @param crc_on Enable cyclic redundancy check (defaults to disabled)
45  */
46  SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz = 1000000, bool crc_on = 0);
47  virtual ~SDBlockDevice();
48 
49  /** Initialize a block device
50  *
51  * @return BD_ERROR_OK(0) - success
52  * BD_ERROR_DEVICE_ERROR - device driver transaction failed
53  * SD_BLOCK_DEVICE_ERROR_NO_DEVICE - device (SD card) is missing or not connected
54  * SD_BLOCK_DEVICE_ERROR_UNUSABLE - unusable card
55  * SD_BLOCK_DEVICE_ERROR_CRC - crc error
56  */
57  virtual int init();
58 
59  /** Deinitialize a block device
60  *
61  * @return BD_ERROR_OK(0) - success
62  */
63  virtual int deinit();
64 
65  /** Read blocks from a block device
66  *
67  * @param buffer Buffer to write blocks to
68  * @param addr Address of block to begin reading from
69  * @param size Size to read in bytes, must be a multiple of read block size
70  * @return BD_ERROR_OK(0) - success
71  * SD_BLOCK_DEVICE_ERROR_NO_DEVICE - device (SD card) is missing or not connected
72  * SD_BLOCK_DEVICE_ERROR_CRC - crc error
73  * SD_BLOCK_DEVICE_ERROR_PARAMETER - invalid parameter
74  * SD_BLOCK_DEVICE_ERROR_NO_RESPONSE - no response from device
75  * SD_BLOCK_DEVICE_ERROR_UNSUPPORTED - unsupported command
76  */
77  virtual int read(void *buffer, mbed::bd_addr_t addr, mbed::bd_size_t size);
78 
79  /** Program blocks to a block device
80  *
81  * @note The blocks must be erased prior to programming
82  *
83  * @param buffer Buffer of data to write to blocks
84  * @param addr Address of block to begin writing to
85  * @param size Size to write in bytes. Must be a multiple of program block size
86  * @return BD_ERROR_OK(0) - success
87  * SD_BLOCK_DEVICE_ERROR_NO_DEVICE - device (SD card) is missing or not connected
88  * SD_BLOCK_DEVICE_ERROR_CRC - crc error
89  * SD_BLOCK_DEVICE_ERROR_PARAMETER - invalid parameter
90  * SD_BLOCK_DEVICE_ERROR_UNSUPPORTED - unsupported command
91  * SD_BLOCK_DEVICE_ERROR_NO_INIT - device is not initialized
92  * SD_BLOCK_DEVICE_ERROR_WRITE - SPI write error
93  * SD_BLOCK_DEVICE_ERROR_ERASE - erase error
94  */
95  virtual int program(const void *buffer, mbed::bd_addr_t addr, mbed::bd_size_t size);
96 
97  /** Mark blocks as no longer in use
98  *
99  * This function provides a hint to the underlying block device that a region of blocks
100  * is no longer in use and may be erased without side effects. Erase must still be called
101  * before programming, but trimming allows flash-translation-layers to schedule erases when
102  * the device is not busy.
103  *
104  * @param addr Address of block to mark as unused
105  * @param size Size to mark as unused in bytes, must be a multiple of erase block size
106  * @return BD_ERROR_OK(0) - success
107  * SD_BLOCK_DEVICE_ERROR_NO_DEVICE - device (SD card) is missing or not connected
108  * SD_BLOCK_DEVICE_ERROR_CRC - crc error
109  * SD_BLOCK_DEVICE_ERROR_PARAMETER - invalid parameter
110  * SD_BLOCK_DEVICE_ERROR_UNSUPPORTED - unsupported command
111  * SD_BLOCK_DEVICE_ERROR_NO_INIT - device is not initialized
112  * SD_BLOCK_DEVICE_ERROR_ERASE - erase error
113  */
114  virtual int trim(mbed::bd_addr_t addr, mbed::bd_size_t size);
115 
116  /** Get the size of a readable block
117  *
118  * @return Size of a readable block in bytes
119  */
120  virtual mbed::bd_size_t get_read_size() const;
121 
122  /** Get the size of a programmable block
123  *
124  * @return Size of a programmable block in bytes
125  * @note Must be a multiple of the read size
126  */
127  virtual mbed::bd_size_t get_program_size() const;
128 
129  /** Get the total size of the underlying device
130  *
131  * @return Size of the underlying device in bytes
132  */
133  virtual mbed::bd_size_t size() const;
134 
135  /** Enable or disable debugging
136  *
137  * @param dbg State of debugging
138  */
139  virtual void debug(bool dbg);
140 
141  /** Set the transfer frequency
142  *
143  * @param freq Transfer frequency
144  * @note Max frequency supported is 25MHZ
145  */
146  virtual int frequency(uint64_t freq);
147 
148  /** Get the BlockDevice class type.
149  *
150  * @return A string representation of the BlockDevice class type.
151  */
152  virtual const char *get_type() const;
153 
154 private:
155  /* Commands : Listed below are commands supported
156  * in SPI mode for SD card : Only Mandatory ones
157  */
158  enum cmdSupported {
159  CMD_NOT_SUPPORTED = -1, /**< Command not supported error */
160  CMD0_GO_IDLE_STATE = 0, /**< Resets the SD Memory Card */
161  CMD1_SEND_OP_COND = 1, /**< Sends host capacity support */
162  CMD6_SWITCH_FUNC = 6, /**< Check and Switches card function */
163  CMD8_SEND_IF_COND = 8, /**< Supply voltage info */
164  CMD9_SEND_CSD = 9, /**< Provides Card Specific data */
165  CMD10_SEND_CID = 10, /**< Provides Card Identification */
166  CMD12_STOP_TRANSMISSION = 12, /**< Forces the card to stop transmission */
167  CMD13_SEND_STATUS = 13, /**< Card responds with status */
168  CMD16_SET_BLOCKLEN = 16, /**< Length for SC card is set */
169  CMD17_READ_SINGLE_BLOCK = 17, /**< Read single block of data */
170  CMD18_READ_MULTIPLE_BLOCK = 18, /**< Card transfers data blocks to host until interrupted
171  by a STOP_TRANSMISSION command */
172  CMD24_WRITE_BLOCK = 24, /**< Write single block of data */
173  CMD25_WRITE_MULTIPLE_BLOCK = 25, /**< Continuously writes blocks of data until
174  'Stop Tran' token is sent */
175  CMD27_PROGRAM_CSD = 27, /**< Programming bits of CSD */
176  CMD32_ERASE_WR_BLK_START_ADDR = 32, /**< Sets the address of the first write
177  block to be erased. */
178  CMD33_ERASE_WR_BLK_END_ADDR = 33, /**< Sets the address of the last write
179  block of the continuous range to be erased.*/
180  CMD38_ERASE = 38, /**< Erases all previously selected write blocks */
181  CMD55_APP_CMD = 55, /**< Extend to Applications specific commands */
182  CMD56_GEN_CMD = 56, /**< General Purpose Command */
183  CMD58_READ_OCR = 58, /**< Read OCR register of card */
184  CMD59_CRC_ON_OFF = 59, /**< Turns the CRC option on or off*/
185  // App Commands
186  ACMD6_SET_BUS_WIDTH = 6,
187  ACMD13_SD_STATUS = 13,
188  ACMD22_SEND_NUM_WR_BLOCKS = 22,
189  ACMD23_SET_WR_BLK_ERASE_COUNT = 23,
190  ACMD41_SD_SEND_OP_COND = 41,
191  ACMD42_SET_CLR_CARD_DETECT = 42,
192  ACMD51_SEND_SCR = 51,
193  };
194 
195  uint8_t _card_type;
196  int _cmd(SDBlockDevice::cmdSupported cmd, uint32_t arg, bool isAcmd = 0, uint32_t *resp = NULL);
197  int _cmd8();
198 
199  /* Move the SD Card into the SPI Mode idle state
200  *
201  * The card is transitioned from SD Card mode to SPI mode by sending the
202  * CMD0 (GO_IDLE_STATE) command with CS asserted. See the notes in the
203  * "SPI Startup" section of the comments at the head of the
204  * implementation file for further details and specification references.
205  *
206  * @return Response form the card. R1_IDLE_STATE (0x1), the successful
207  * response from CMD0. R1_XXX_XXX for more response
208  */
209  uint32_t _go_idle_state();
210  int _initialise_card();
211 
212  mbed::bd_size_t _sectors;
213  mbed::bd_size_t _sd_sectors();
214 
215  bool _is_valid_trim(mbed::bd_addr_t addr, mbed::bd_size_t size);
216 
217  /* SPI functions */
218  mbed::Timer _spi_timer; /**< Timer Class object used for busy wait */
219  uint32_t _init_sck; /**< Initial SPI frequency */
220  uint32_t _transfer_sck; /**< SPI frequency during data transfer/after initialization */
221  mbed::SPI _spi; /**< SPI Class object */
222 
223  /* SPI initialization function */
224  void _spi_init();
225  uint8_t _cmd_spi(SDBlockDevice::cmdSupported cmd, uint32_t arg);
226  void _spi_wait(uint8_t count);
227 
228  bool _wait_token(uint8_t token); /**< Wait for token */
229  bool _wait_ready(uint16_t ms = 300); /**< 300ms default wait for card to be ready */
230  int _read(uint8_t *buffer, uint32_t length);
231  int _read_bytes(uint8_t *buffer, uint32_t length);
232  uint8_t _write(const uint8_t *buffer, uint8_t token, uint32_t length);
233  int _freq(void);
234 
235  /* Chip Select and SPI mode select */
236  mbed::DigitalOut _cs;
237  void _select();
238  void _deselect();
239 
240  virtual void lock()
241  {
242  _mutex.lock();
243  }
244 
245  virtual void unlock()
246  {
247  _mutex.unlock();
248  }
249 
250  PlatformMutex _mutex;
251  static const uint32_t _block_size;
252  uint32_t _erase_size;
253  bool _is_initialized;
254  bool _dbg;
255  uint32_t _init_ref_count;
256 
257 #if MBED_CONF_SD_CRC_ENABLED
258  bool _crc_on;
261 #endif
262 };
263 
264 #endif /* DEVICE_SPI */
265 
266 #endif /* MBED_SD_BLOCK_DEVICE_H */
virtual int program(const void *buffer, mbed::bd_addr_t addr, mbed::bd_size_t size)
Program blocks to a block device.
virtual void debug(bool dbg)
Enable or disable debugging.
A hardware device capable of writing and reading blocks.
Definition: BlockDevice.h:47
virtual int init()
Initialize a block device.
virtual mbed::bd_size_t size() const
Get the total size of the underlying device.
SDBlockDevice class.
Definition: SDBlockDevice.h:35
The PlatformMutex class is used to synchronize the execution of threads.
Definition: PlatformMutex.h:47
SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz=1000000, bool crc_on=0)
Creates an SDBlockDevice on a SPI bus specified by pins.
void unlock()
Unlock a PlatformMutex that the same thread has previously locked.
Definition: PlatformMutex.h:81
void lock()
Wait until a PlatformMutex becomes available.
Definition: PlatformMutex.h:71
virtual int read(void *buffer, mbed::bd_addr_t addr, mbed::bd_size_t size)
Read blocks from a block device.
virtual mbed::bd_size_t get_read_size() const
Get the size of a readable block.
A digital output, used for setting the state of a pin.
Definition: DigitalOut.h:47
A SPI Master, used for communicating with SPI slave devices.
Definition: SPI.h:82
virtual mbed::bd_size_t get_program_size() const
Get the size of a programmable block.
virtual int frequency(uint64_t freq)
Set the transfer frequency.
virtual int deinit()
Deinitialize a block device.
virtual const char * get_type() const
Get the BlockDevice class type.
virtual int trim(mbed::bd_addr_t addr, mbed::bd_size_t size)
Mark blocks as no longer in use.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.