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
62 static constexpr uint32_t _block_size = 512;
75 PinName miso = MBED_CONF_SD_SPI_MISO,
76 PinName sclk = MBED_CONF_SD_SPI_CLK,
77 PinName cs = MBED_CONF_SD_SPI_CS,
78 uint64_t hz = MBED_CONF_SD_TRX_FREQUENCY,
79 bool crc_on = MBED_CONF_SD_CRC_ENABLED);
89 PinName cs = MBED_CONF_SD_SPI_CS,
90 uint64_t hz = MBED_CONF_SD_TRX_FREQUENCY,
91 bool crc_on = MBED_CONF_SD_CRC_ENABLED);
220 CMD_NOT_SUPPORTED = -1,
221 CMD0_GO_IDLE_STATE = 0,
222 CMD1_SEND_OP_COND = 1,
223 CMD6_SWITCH_FUNC = 6,
224 CMD8_SEND_IF_COND = 8,
227 CMD12_STOP_TRANSMISSION = 12,
228 CMD13_SEND_STATUS = 13,
229 CMD16_SET_BLOCKLEN = 16,
230 CMD17_READ_SINGLE_BLOCK = 17,
231 CMD18_READ_MULTIPLE_BLOCK = 18,
233 CMD24_WRITE_BLOCK = 24,
234 CMD25_WRITE_MULTIPLE_BLOCK = 25,
236 CMD27_PROGRAM_CSD = 27,
237 CMD32_ERASE_WR_BLK_START_ADDR = 32,
239 CMD33_ERASE_WR_BLK_END_ADDR = 33,
245 CMD59_CRC_ON_OFF = 59,
247 ACMD6_SET_BUS_WIDTH = 6,
248 ACMD13_SD_STATUS = 13,
249 ACMD22_SEND_NUM_WR_BLOCKS = 22,
250 ACMD23_SET_WR_BLK_ERASE_COUNT = 23,
251 ACMD41_SD_SEND_OP_COND = 41,
252 ACMD42_SET_CLR_CARD_DETECT = 42,
253 ACMD51_SEND_SCR = 51,
257 int _cmd(SDBlockDevice::cmdSupported cmd, uint32_t arg,
bool isAcmd = 0, uint32_t *resp = NULL);
270 uint32_t _go_idle_state();
271 int _initialise_card();
279 mbed::Timer _spi_timer;
281 uint32_t _transfer_sck;
286 uint8_t _cmd_spi(SDBlockDevice::cmdSupported cmd, uint32_t arg);
287 void _spi_wait(uint8_t count);
289 bool _wait_token(uint8_t token);
290 bool _wait_ready(std::chrono::duration<uint32_t, std::milli> timeout = std::chrono::milliseconds{300});
291 int _read(uint8_t *buffer, uint32_t length);
292 int _read_bytes(uint8_t *buffer, uint32_t length);
293 uint8_t _write(
const uint8_t *buffer, uint8_t token, uint32_t length);
295 void _preclock_then_select();
296 void _postclock_then_deselect();
303 virtual void unlock()
309 uint32_t _erase_size;
310 bool _is_initialized;
312 uint32_t _init_ref_count;
314#if MBED_CONF_SD_CRC_ENABLED
319 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.
CacheAlignedBuffer type designed for static allocation.
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.