18#ifndef MBED_SD_BLOCK_DEVICE_H
19#define MBED_SD_BLOCK_DEVICE_H
24#include "blockdevice/BlockDevice.h"
25#include "drivers/SPI.h"
26#include "drivers/Timer.h"
27#include "drivers/MbedCRC.h"
28#include "drivers/DigitalOut.h"
29#include "platform/platform.h"
30#include "rtos/Mutex.h"
31#include "hal/static_pinmap.h"
33#ifndef MBED_CONF_SD_SPI_MOSI
34#define MBED_CONF_SD_SPI_MOSI NC
36#ifndef MBED_CONF_SD_SPI_MISO
37#define MBED_CONF_SD_SPI_MISO NC
39#ifndef MBED_CONF_SD_SPI_CLK
40#define MBED_CONF_SD_SPI_CLK NC
42#ifndef MBED_CONF_SD_SPI_CS
43#define MBED_CONF_SD_SPI_CS NC
45#ifndef MBED_CONF_SD_INIT_FREQUENCY
46#define MBED_CONF_SD_INIT_FREQUENCY 100000
48#ifndef MBED_CONF_SD_TRX_FREQUENCY
49#define MBED_CONF_SD_TRX_FREQUENCY 1000000
51#ifndef MBED_CONF_SD_CRC_ENABLED
52#define MBED_CONF_SD_CRC_ENABLED 0
71 PinName miso = MBED_CONF_SD_SPI_MISO,
72 PinName sclk = MBED_CONF_SD_SPI_CLK,
73 PinName cs = MBED_CONF_SD_SPI_CS,
74 uint64_t hz = MBED_CONF_SD_TRX_FREQUENCY,
75 bool crc_on = MBED_CONF_SD_CRC_ENABLED);
85 PinName cs = MBED_CONF_SD_SPI_CS,
86 uint64_t hz = MBED_CONF_SD_TRX_FREQUENCY,
87 bool crc_on = MBED_CONF_SD_CRC_ENABLED);
216 CMD_NOT_SUPPORTED = -1,
217 CMD0_GO_IDLE_STATE = 0,
218 CMD1_SEND_OP_COND = 1,
219 CMD6_SWITCH_FUNC = 6,
220 CMD8_SEND_IF_COND = 8,
223 CMD12_STOP_TRANSMISSION = 12,
224 CMD13_SEND_STATUS = 13,
225 CMD16_SET_BLOCKLEN = 16,
226 CMD17_READ_SINGLE_BLOCK = 17,
227 CMD18_READ_MULTIPLE_BLOCK = 18,
229 CMD24_WRITE_BLOCK = 24,
230 CMD25_WRITE_MULTIPLE_BLOCK = 25,
232 CMD27_PROGRAM_CSD = 27,
233 CMD32_ERASE_WR_BLK_START_ADDR = 32,
235 CMD33_ERASE_WR_BLK_END_ADDR = 33,
241 CMD59_CRC_ON_OFF = 59,
243 ACMD6_SET_BUS_WIDTH = 6,
244 ACMD13_SD_STATUS = 13,
245 ACMD22_SEND_NUM_WR_BLOCKS = 22,
246 ACMD23_SET_WR_BLK_ERASE_COUNT = 23,
247 ACMD41_SD_SEND_OP_COND = 41,
248 ACMD42_SET_CLR_CARD_DETECT = 42,
249 ACMD51_SEND_SCR = 51,
253 int _cmd(SDBlockDevice::cmdSupported cmd, uint32_t arg,
bool isAcmd = 0, uint32_t *resp = NULL);
266 uint32_t _go_idle_state();
267 int _initialise_card();
275 mbed::Timer _spi_timer;
277 uint32_t _transfer_sck;
282 uint8_t _cmd_spi(SDBlockDevice::cmdSupported cmd, uint32_t arg);
283 void _spi_wait(uint8_t count);
285 bool _wait_token(uint8_t token);
286 bool _wait_ready(std::chrono::duration<uint32_t, std::milli> timeout = std::chrono::milliseconds{300});
287 int _read(uint8_t *buffer, uint32_t length);
288 int _read_bytes(uint8_t *buffer, uint32_t length);
289 uint8_t _write(
const uint8_t *buffer, uint8_t token, uint32_t length);
291 void _preclock_then_select();
292 void _postclock_then_deselect();
299 virtual void unlock()
305 static const uint32_t _block_size;
306 uint32_t _erase_size;
307 bool _is_initialized;
309 uint32_t _init_ref_count;
311#if MBED_CONF_SD_CRC_ENABLED
316 bool _async_spi_enabled =
false;
virtual const char * get_type() const
Get the BlockDevice class type.
virtual mbed::bd_size_t get_read_size() const
Get the size of a readable block.
virtual int read(void *buffer, mbed::bd_addr_t addr, mbed::bd_size_t size)
Read blocks from a block device.
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.
virtual mbed::bd_size_t get_program_size() const
Get the size of a programmable block.
virtual mbed::bd_size_t size() const
Get the total size of the underlying device.
virtual int deinit()
Deinitialize a block device.
SDBlockDevice(const spi_pinmap_t &spi_pinmap, PinName cs=NC, uint64_t hz=1000000, bool crc_on=0)
Creates an SDBlockDevice on a SPI bus specified by pins (using static pin-map)
virtual int frequency(uint64_t freq)
Set the transfer frequency.
virtual int trim(mbed::bd_addr_t addr, mbed::bd_size_t size)
Mark blocks as no longer in use.
virtual int init()
Initialize a block device.
SDBlockDevice(PinName mosi=NC, PinName miso=NC, PinName sclk=NC, PinName cs=NC, uint64_t hz=1000000, bool crc_on=0)
Creates an SDBlockDevice on a SPI bus specified by pins (using dynamic pin-map)
void set_async_spi_mode(bool enabled, DMAUsage dma_usage_hint=DMAUsage::DMA_USAGE_NEVER)
Configure the usage of asynchronous SPI by this class.
A hardware device capable of writing and reading blocks.
An SPI Master, used for communicating with SPI slave devices.
The Mutex class is used to synchronize the execution of threads.
void unlock()
Unlock the mutex that has previously been locked by the same thread.
void lock()
Wait until a Mutex becomes available.
DMAUsage
Enumeration of possible DMA usage hints.
uint64_t bd_size_t
Type representing a quantity of 8-bit bytes.
uint64_t bd_addr_t
Type representing the address of a specific block.