Low-level SDIO/SD/MMC peripheral driver. More...
Low-level SDIO/SD/MMC peripheral driver.
The low-level SDIO/SD/MMC peripheral driver interface as used by high-level SDIO/SD/MMC device API functions. It has to be implemented for a specific CPU.
#include <sdmmc.h>
Data Fields | |
void(* | init )(sdmmc_dev_t *dev) |
Basic initialization of the given SDIO/SD/MMC device. | |
int(* | send_cmd )(sdmmc_dev_t *dev, sdmmc_cmd_t cmd_idx, uint32_t arg, sdmmc_resp_t resp_type, uint32_t *resp) |
Send command to SDIO/SD/MMC Card and optionally wait for response. | |
int(* | card_init )(sdmmc_dev_t *dev) |
Card Initialization and Identification. | |
int(* | set_bus_width )(sdmmc_dev_t *dev, sdmmc_bus_width_t width) |
Set data bus width. | |
int(* | set_clock_rate )(sdmmc_dev_t *dev, sdmmc_clock_rate_t rate) |
Set SD CLK signal rate. | |
int(* | enable_clock )(sdmmc_dev_t *dev, bool enable) |
Enable or disable the SD CLK signal. | |
int(* | xfer_prepare )(sdmmc_dev_t *dev, sdmmc_xfer_desc_t *xfer) |
Prepare a data transfer. | |
int(* | xfer_execute )(sdmmc_dev_t *dev, sdmmc_xfer_desc_t *xfer, const void *data_wr, void *data_rd, uint16_t *done) |
Execute the data transfer. | |
int(* | xfer_finish )(sdmmc_dev_t *dev, sdmmc_xfer_desc_t *xfer) |
Finish the data transfer. | |
int(* sdmmc_driver_t::card_init) (sdmmc_dev_t *dev) |
Card Initialization and Identification.
dev
must not be NULL
.[in] | dev | SDIO/SD/MMC device to be used |
0 | on success |
-ENODEV | if card is not present or not usable |
-ENOTSUP | if card is not supported or can't operate under supplied voltage |
-EFAULT | on card status error |
-ETIMEDOUT | on card initialization and identification timeout |
-EBADMSG | on CRC7 error |
-EIO | on not further specified error incl. hardware errors |
int(* sdmmc_driver_t::enable_clock) (sdmmc_dev_t *dev, bool enable) |
Enable or disable the SD CLK signal.
The function is used by the SDIO/SD/MMC device API functions to enable or disable the SD CLK signal if the SDIO/SD/MMC peripheral driver does not support the Auto CLK feature (periph_sdmmc_auto_clk). It can be left NULL if the SDIO/SD/MMC peripheral driver does not support enabling or disabling the SD CLK signal.
[in] | dev | SDIO/SD/MMC device to be used |
[in] | enable | enable SD CLK signal on true or disable the SD CLK signal on false |
0 | on success |
-EIO | if the SD CLK signal could not be enabled or disabled |
void(* sdmmc_driver_t::init) (sdmmc_dev_t *dev) |
Basic initialization of the given SDIO/SD/MMC device.
Low-level SDIO/SD/MMC peripheral driver function for basic initialization of the peripheral including pin configuration of used pins. It is called by sdmmc_init during the board initialization to prepare the SDIO/SD/MMC peripheral for further usage. Specific initialization parameters required for this initialization are defined in the board's periph_conf.h
.
Errors like configuration parameter problems are not signaled by return values, but by using the assert()
.
dev
must not be NULL
.[in] | dev | SDIO/SD/MMC device to initialize |
int(* sdmmc_driver_t::send_cmd) (sdmmc_dev_t *dev, sdmmc_cmd_t cmd_idx, uint32_t arg, sdmmc_resp_t resp_type, uint32_t *resp) |
Send command to SDIO/SD/MMC Card and optionally wait for response.
Low-level SDIO/SD/MMC peripheral driver function to send command cmd_idx
with argument arg
to the SDIO/SD/MMC card. resp_type
specifies the type of the response expected.
To ensure that the sdmmc_send_acmd function is used for application specific commands, the function must fail if the command cmd_idx
is an application specific command (ACMDx). Use
in the implementation of this function for that purpose.
The response has to be stored word-wise in host byte order in the buffer provided by resp
as follows:
resp_type
= SDMMC_NO_R (No Response): resp
can be NULLresp_tpye
= SDMMC_R2 (Long Response): resp
= { R[127:96], R[95:64], R[63:32], R[31:0] }resp_type
= anything else (Short Response): resp
= { R[39:8] }The buffer provided by resp
can be NULL if the response is not needed. However, the low-level SDIO/SD/MMC peripheral driver must receive the expected response, but does not store it in resp
in that case.
0b111111
. The driver must check the CRC field for this response.dev
must not be NULL
.[in] | dev | SDIO/SD/MMC device to be used |
[in] | cmd_idx | Command index |
[in] | arg | Command argument |
[in] | resp_type | Type of response expected |
[out] | resp | Buffer of 32-bit words to store the response if needed, otherwise NULL |
0 | on success |
-ENODEV | if card is not present or not usable |
-ENOTSUP | if card does not support the command or is in wrong state |
-EFAULT | on card status error |
-ETIMEDOUT | on timeout condition |
-EBADMSG | on CRC7 error in response |
-EIO | on not further specified error incl. hardware errors |
int(* sdmmc_driver_t::set_bus_width) (sdmmc_dev_t *dev, sdmmc_bus_width_t width) |
Set data bus width.
Set the data bus width used by the SDIO/SD/MMC peripheral. The function is called by the high-level SDIO/SD/MMC device function sdmmc_card_init at the end of the card initialization and identification procedure to change the data bus width used by the SDIO/SD/MMC peripheral. The data bus width of the card has been already changed at that time by sending the ACMD6 (SET_BUS_WIDTH
) command.
Supported data bus width depend on
In identification mode, always 1-bit data bus width is used. When switching from the identification mode to the data transfer mode, the data bus width is changed. In data transfer mode, the data bus width depends on the type of the used card:
The data bus width width
is the minimum of the data bus width supported by the identified card and the data bus width sdmmc_dev_t::bus_width configured for the SDIO/SD/MMC peripheral. The low-level SDIO/SD/MMC peripheral driver is responsible for correctly setting sdmmc_dev_t::bus_width in the sdmmc_driver_t::init function.
dev
must not be NULL
.[in] | dev | SDIO/SD/MMC device to be used |
[in] | width | Data bus width to be set |
0 | on success |
-ENOTSUP | if SDIO/SD/MMC peripheral does not support the width |
-EIO | on not further specified error incl. hardware errors |
int(* sdmmc_driver_t::set_clock_rate) (sdmmc_dev_t *dev, sdmmc_clock_rate_t rate) |
Set SD CLK signal rate.
Set the SD CLK rate used by the SDIO/SD/MMC peripheral. The clock frequency in identification mode f_OD is fixed and is 400 kHz. The actual clock frequency in data transfer mode f_PP depends on the SDIO/SD/MMC device and the card used.
The function is called by the high-level SDIO/SD/MMC device API function sdmmc_card_init at the end of the card identification procedure with rate
set to any of the clock rates defined in sdmmc_clock_rate_t. The low-level SDIO/SD/MMC peripheral is responsible to set the clock rate to the highest value it supports for the identified card type.
dev
must not be NULL
.[in] | dev | SDIO/SD/MMC device to be used |
[in] | rate | Clock rate to be set |
0 | on success |
-ENOTSUP | if SDIO/SD/MMC peripheral does not support the clock rate |
-EIO | on not further specified error incl. hardware errors |
int(* sdmmc_driver_t::xfer_execute) (sdmmc_dev_t *dev, sdmmc_xfer_desc_t *xfer, const void *data_wr, void *data_rd, uint16_t *done) |
Execute the data transfer.
Low-level SDIO/SD/MMC peripheral driver function to transfer the data (read or write) by the SDIO/SD/MMC peripheral.
It is called by the high-level SDIO/SD/MMC device API function sdmmc_xfer after it sent the block-oriented, stream or byte/multi-byte command to start the transfer from or to the card.
The function returns the number of transferred blocks in done
. Most SDIO/SD/MMC peripherals use a block or byte counter when transferring data, which can be used for this purpose.
0
in done
in case of an error or sdmmc_xfer_desc_t::block_num on success.dev
and xfer
must not be NULL
. data_rd
must not be NULL
for read transfers and data_wr
must not be NULL
for write transfers.[in] | dev | SDIO/SD/MMC device to be used |
[in] | xfer | Transfer descriptor of type sdmmc_xfer_desc_t |
[in] | data_wr | Buffer with data to write in write transfers, NULL otherwise |
[out] | data_rd | Buffer for data to read in read transfers, NULL otherwise |
[out] | done | Number of blocks transferred, can be NULL |
0 | on success |
-ENODEV | if card is not present or not usable |
-ENOTSUP | if card does not support a used command or is in wrong state |
-EBUSY | if card is busy |
-EFAULT | on card status error |
-ETIMEDOUT | on timeout condition |
-EINVAL | on invalid transfer parameters |
-EBADMSG | on CRC7 error in data |
-ENOMEM | on RX FIFO overflow or TX FIFO underrun error |
-EIO | on not further specified error incl. hardware errors |
int(* sdmmc_driver_t::xfer_finish) (sdmmc_dev_t *dev, sdmmc_xfer_desc_t *xfer) |
Finish the data transfer.
Low-level SDIO/SD/MMC peripheral driver function to terminate a data transfer (read or write) in the SDIO/SD/MMC peripheral.
It is called by the high-level SDIO/SD/MMC device API function sdmmc_xfer after the data transfer has been executed and the stop command (CMD12) has been sent if necessary.
dev
and xfer
must not be NULL
.[in] | dev | SDIO/SD/MMC device to be used |
[in] | xfer | Transfer descriptor of type sdmmc_xfer_desc_t |
0 | on success |
-EIO | on not further specified error incl. hardware errors |
int(* sdmmc_driver_t::xfer_prepare) (sdmmc_dev_t *dev, sdmmc_xfer_desc_t *xfer) |
Prepare a data transfer.
Low-level SDIO/SD/MMC peripheral driver function to prepare a data transfer (read or write) in the SDIO/SD/MMC peripheral.
It is called by the high-level SDIO/SD/MMC device API function sdmmc_xfer before it sends a block-oriented, stream or byte/multi-byte command to the card to start the transfer from or to the card.
A typical activity of this function is the configuration of the DMA transfer.
dev
and xfer
must not be NULL
.[in] | dev | SDIO/SD/MMC device to be used |
[in] | xfer | Transfer descriptor of type sdmmc_xfer_desc_t |
0 | on success |
-EINVAL | on invalid transfer parameters |
-EIO | on not further specified error incl. hardware errors |