29 #if (HAL_USE_SDC == TRUE) || defined(__DOXYGEN__) 39 MMC_SWITCH_COMMAND_SET = 0,
40 MMC_SWITCH_SET_BITS = 1,
41 MMC_SWITCH_CLEAR_BITS = 2,
42 MMC_SWITCH_WRITE_BYTE = 3
57 SD_SWITCH_FUNCTION_SPEED = 0,
58 SD_SWITCH_FUNCTION_CMD_SYSTEM = 1,
59 SD_SWITCH_FUNCTION_DRIVER_STRENGTH = 2,
60 SD_SWITCH_FUNCTION_CURRENT_LIMIT = 3
76 (
bool (*)(
void *))sdc_lld_is_card_inserted,
77 (bool (*)(
void *))sdc_lld_is_write_protected,
80 (bool (*)(
void *, uint32_t, uint8_t *, uint32_t))
sdcRead,
81 (bool (*)(
void *, uint32_t,
const uint8_t *, uint32_t))
sdcWrite,
106 sdcp->
cardmode = SDC_MODE_CARDTYPE_SDV20;
108 if (((resp[0] >> 8U) & 0xFU) != 1U) {
120 sdcp->
cardmode = SDC_MODE_CARDTYPE_MMC;
123 sdcp->
cardmode = SDC_MODE_CARDTYPE_SDV11;
155 if ((resp[0] & 0x80000000U) != 0U) {
156 if ((resp[0] & 0x40000000U) != 0U) {
157 sdcp->
cardmode |= SDC_MODE_HIGH_CAPACITY;
186 if ((sdcp->
cardmode & SDC_MODE_CARDTYPE_MASK) == SDC_MODE_CARDTYPE_SDV20) {
202 if ((resp[0] & 0x80000000U) != 0U) {
203 if ((resp[0] & 0x40000000U) != 0U) {
204 sdcp->
cardmode |= SDC_MODE_HIGH_CAPACITY;
230 uint32_t value, uint32_t cmd_set) {
235 return ((uint32_t)access << 24U) | (idx << 16U) | (value << 8U) | cmd_set;
252 uint32_t ret = 0xFFFFFF;
256 ret &= ~((uint32_t)0xFU << ((uint32_t)
function * 4U));
257 ret |= value << ((uint32_t)
function * 4U);
258 return ret | ((uint32_t)mode << 31U);
272 const uint8_t *buf) {
274 unsigned start = 12U - ((unsigned)
function * 2U);
276 return ((uint16_t)buf[start] << 8U) | (uint16_t)buf[start + 1U];
292 const uint8_t *buf) {
297 tmp = ((uint32_t)buf[14] << 16U) |
298 ((uint32_t)buf[15] << 8U) |
300 status = (tmp >> ((uint32_t)
function * 4U)) & 0xFU;
301 if (0xFU != status) {
325 *clk = SDC_CLK_25MHz;
330 *clk = SDC_CLK_25MHz;
335 if (sdc_lld_read_special(sdcp, tmp, N, MMCSD_CMD_SWITCH, 0)) {
345 if (sdc_lld_read_special(sdcp, tmp, N, MMCSD_CMD_SWITCH, cmdarg)) {
351 *clk = SDC_CLK_50MHz;
354 *clk = SDC_CLK_25MHz;
379 *clk = SDC_CLK_25MHz;
382 if (NULL == scratchpad) {
389 *clk = SDC_CLK_50MHz;
409 if (SDC_MODE_CARDTYPE_MMC == (sdcp->
cardmode & SDC_MODE_CARDTYPE_MASK)) {
519 #if SDC_NICE_WAITING == TRUE 558 sdcp->
errors = SDC_NO_ERROR;
646 if ((sdcp->
cardmode & SDC_MODE_CARDTYPE_MASK) == SDC_MODE_CARDTYPE_MMC) {
670 sdcp->
rca, sdcp->csd)) {
687 if (SDC_MODE_CARDTYPE_MMC == (sdcp->
cardmode & SDC_MODE_CARDTYPE_MASK)) {
694 if (NULL == ext_csd) {
698 if(sdc_lld_read_special(sdcp, ext_csd, 512, MMCSD_CMD_SEND_EXT_CSD, 0)) {
723 switch (sdcp->
cardmode & SDC_MODE_CARDTYPE_MASK) {
724 case SDC_MODE_CARDTYPE_SDV11:
725 case SDC_MODE_CARDTYPE_SDV20:
730 case SDC_MODE_CARDTYPE_MMC:
808 osalDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0U));
811 if ((startblk + n - 1U) > sdcp->capacity) {
812 sdcp->
errors |= SDC_OVERFLOW_ERROR;
843 const uint8_t *buf, uint32_t n) {
846 osalDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0U));
849 if ((startblk + n - 1U) > sdcp->capacity) {
850 sdcp->
errors |= SDC_OVERFLOW_ERROR;
880 sdcp->
errors = SDC_NO_ERROR;
935 bdip->
blk_num = sdcp->capacity;
964 if ((sdcp->
cardmode & SDC_MODE_HIGH_CAPACITY) != 0U) {
974 startblk, resp) != HAL_SUCCESS) ||
980 endblk, resp) != HAL_SUCCESS) ||
986 0, resp) != HAL_SUCCESS) ||
bool sdc_lld_sync(SDCDriver *sdcp)
Waits for card idle condition.
bool sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, uint32_t *resp)
Sends an SDIO command with a short response expected and CRC.
static bool sdc_detect_bus_clk(SDCDriver *sdcp, sdcbusclk_t *clk)
Reads supported bus clock and switch SDC to appropriate mode.
bool sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, uint32_t *resp)
Sends an SDIO command with a short response expected.
bool _sdc_wait_for_transfer_state(SDCDriver *sdcp)
Wait for the card to complete pending operations.
static uint32_t mmc_cmd6_construct(mmc_switch_t access, uint32_t idx, uint32_t value, uint32_t cmd_set)
Constructs CMD6 argument for MMC.
bool sdcConnect(SDCDriver *sdcp)
Performs the initialization procedure on the inserted card.
static uint32_t sdc_cmd6_construct(sd_switch_t mode, sd_switch_function_t function, uint32_t value)
Constructs CMD6 argument for SDC.
uint32_t _mmcsd_get_capacity_ext(const uint8_t *ext_csd)
Extract MMC card capacity from EXT_CSD.
mmc_switch_t
MMC switch mode.
const struct SDCDriverVMT * vmt
Virtual Methods Table.
sdcbusmode_t bus_width
Bus width.
#define MMCSD_BLOCK_SIZE
Fixed block size for MMC/SD block devices.
static bool mmc_init(SDCDriver *sdcp)
Init procedure for MMC.
static bool mmc_detect_bus_clk(SDCDriver *sdcp, sdcbusclk_t *clk)
Reads supported bus clock and switch MMC to appropriate mode.
static void osalSysUnlock(void)
Leaves a critical zone from thread context.
void sdcInit(void)
SDC Driver initialization.
bool sdcDisconnect(SDCDriver *sdcp)
Brings the driver in a state safe for card removal.
#define MMCSD_CMD8_PATTERN
Fixed pattern for CMD8.
bool sdcErase(SDCDriver *sdcp, uint32_t startblk, uint32_t endblk)
Erases the supplied blocks.
#define SDC_INIT_OCR_V20
OCR initialization constant for V20 cards.
void sdc_lld_stop_clk(SDCDriver *sdcp)
Stops the SDIO clock.
bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, uint32_t *resp)
Sends an SDIO command with a long response expected and CRC.
#define osalThreadSleepMilliseconds(msecs)
Delays the invoking thread for the specified number of milliseconds.
sd_switch_function_t
SDC switch function.
bool sdcRead(SDCDriver *sdcp, uint32_t startblk, uint8_t *buf, uint32_t n)
Reads one or more blocks.
void sdc_lld_start(SDCDriver *sdcp)
Configures and activates the SDC peripheral.
void sdc_lld_init(void)
Low level SDC driver initialization.
SDCDriver virtual methods table.
uint32_t blk_num
Total number of blocks.
sdcflags_t sdcGetAndClearErrors(SDCDriver *sdcp)
Returns the errors mask associated to the previous operation.
void sdcObjectInit(SDCDriver *sdcp)
Initializes the standard part of a SDCDriver structure.
void sdc_lld_set_data_clk(SDCDriver *sdcp, sdcbusclk_t clk)
Sets the SDIO clock to data mode (25MHz or less).
void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg)
Sends an SDIO command with no response expected.
#define osalDbgCheck(c)
Function parameters check.
static bool sdc_init(SDCDriver *sdcp)
Init procedure for SDC.
uint32_t _mmcsd_get_slice(const uint32_t *data, uint32_t end, uint32_t start)
Gets a bit field from a words array.
sdcflags_t errors
Errors flags.
static const struct SDCDriverVMT sdc_vmt
Virtual methods table.
#define MMCSD_R1_STS(r1)
Returns the status field of an R1 response.
sdcmode_t cardmode
Various flags regarding the mounted card.
static bool mmc_set_bus_width(SDCDriver *sdcp)
Sets bus width for MMC.
sdcbusclk_t
Max supported clock.
bool sdcSync(SDCDriver *sdcp)
Waits for card idle condition.
static bool sdc_set_bus_width(SDCDriver *sdcp)
Sets bus width for SDC.
bool sdc_lld_write(SDCDriver *sdcp, uint32_t startblk, const uint8_t *buf, uint32_t n)
Writes one or more blocks.
#define SDC_INIT_RETRY
Number of initialization attempts before rejecting the card.
static uint16_t sdc_cmd6_extract_info(sd_switch_function_t function, const uint8_t *buf)
Extracts information from CMD6 answer.
bool sdcGetInfo(SDCDriver *sdcp, BlockDeviceInfo *bdip)
Returns the media info.
bool sdc_lld_read(SDCDriver *sdcp, uint32_t startblk, uint8_t *buf, uint32_t n)
Reads one or more blocks.
static void osalSysLock(void)
Enters a critical zone from thread context.
uint32_t sdcflags_t
SDC Driver condition flags type.
bool sdcWrite(SDCDriver *sdcp, uint32_t startblk, const uint8_t *buf, uint32_t n)
Writes one or more blocks.
sd_switch_t
SDC switch mode.
Structure representing an SDC driver.
static bool detect_bus_clk(SDCDriver *sdcp, sdcbusclk_t *clk)
Reads supported bus clock and switch card to appropriate mode.
uint32_t blk_size
Block size in bytes.
void sdcStart(SDCDriver *sdcp, const SDCConfig *config)
Configures and activates the SDC peripheral.
#define osalDbgAssert(c, remark)
Condition assertion.
#define MMCSD_CSD_MMC_CSD_STRUCTURE_SLICE
Slice position of values in CSD register.
uint32_t _mmcsd_get_capacity(const uint32_t *csd)
Extract card capacity from a CSD.
void sdc_lld_start_clk(SDCDriver *sdcp)
Starts the SDIO clock and sets it to init mode (400kHz or less).
void sdcStop(SDCDriver *sdcp)
Deactivates the SDC peripheral.
_mmcsd_block_device_data const SDCConfig * config
Current configuration data.
static bool mode_detect(SDCDriver *sdcp)
Detects card mode.
#define SDC_INIT_OCR
OCR initialization constant for non-V20 cards.
void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode)
Switches the bus to 4 bits mode.
void sdc_lld_stop(SDCDriver *sdcp)
Deactivates the SDC peripheral.
static bool sdc_cmd6_check_status(sd_switch_function_t function, const uint8_t *buf)
Checks status after switching using CMD6.
uint8_t * scratchpad
Working area for memory consuming operations.
Driver configuration structure.
#define MMCSD_R1_ERROR(r1)
Evaluates to true if the R1 response contains error flags.