diff --git a/boards/OLIMEX_LPC_P2148/board.c b/boards/OLIMEX_LPC_P2148/board.c index d55fc61d4..b7e72f7c3 100644 --- a/boards/OLIMEX_LPC_P2148/board.c +++ b/boards/OLIMEX_LPC_P2148/board.c @@ -65,6 +65,21 @@ void __early_init(void) { lpc214x_clock_init(); } +#if HAL_USE_MMC_SPI +/* Board-related functions related to the MMC_SPI driver.*/ +bool_t mmc_lld_is_card_inserted(MMCDriver *mmcp) { + + (void)mmcp; + return !palReadPad(IOPORT2, PB_CP1); +} + +bool_t mmc_lld_is_write_protected(MMCDriver *mmcp) { + + (void)mmcp; + return palReadPad(IOPORT2, PB_WP1); +} +#endif + /* * Board-specific initialization code. */ diff --git a/boards/OLIMEX_SAM7_EX256/board.c b/boards/OLIMEX_SAM7_EX256/board.c index 2d4d2966e..7b4f016f5 100644 --- a/boards/OLIMEX_SAM7_EX256/board.c +++ b/boards/OLIMEX_SAM7_EX256/board.c @@ -74,6 +74,21 @@ void __early_init(void) { at91sam7_clock_init(); } +#if HAL_USE_MMC_SPI +/* Board-related functions related to the MMC_SPI driver.*/ +bool_t mmc_lld_is_card_inserted(MMCDriver *mmcp) { + + (void)mmcp; + return !palReadPad(IOPORT2, PIOB_MMC_CP); +} + +bool_t mmc_lld_is_write_protected(MMCDriver *mmcp) { + + (void)mmcp; + return palReadPad(IOPORT2, PIOB_MMC_WP); +} +#endif + /* * Board-specific initialization code. */ diff --git a/boards/OLIMEX_SAM7_P256/board.c b/boards/OLIMEX_SAM7_P256/board.c index bb79437a8..60c6b2761 100644 --- a/boards/OLIMEX_SAM7_P256/board.c +++ b/boards/OLIMEX_SAM7_P256/board.c @@ -68,6 +68,21 @@ void __early_init(void) { at91sam7_clock_init(); } +#if HAL_USE_MMC_SPI +/* Board-related functions related to the MMC_SPI driver.*/ +bool_t mmc_lld_is_card_inserted(MMCDriver *mmcp) { + + (void)mmcp; + return !palReadPad(IOPORT1, PIOA_MMC_CP); +} + +bool_t mmc_lld_is_write_protected(MMCDriver *mmcp) { + + (void)mmcp; + return palReadPad(IOPORT1, PIOA_MMC_WP); +} +#endif + /* * Board-specific initialization code. */ diff --git a/demos/ARM7-AT91SAM7S-FATFS-GCC/main.c b/demos/ARM7-AT91SAM7S-FATFS-GCC/main.c index 8b6e0d32b..fea6e72b9 100644 --- a/demos/ARM7-AT91SAM7S-FATFS-GCC/main.c +++ b/demos/ARM7-AT91SAM7S-FATFS-GCC/main.c @@ -61,15 +61,8 @@ static SPIConfig ls_spicfg = { (MIN_SPI_BITRATE << 8) | AT91C_SPI_NCPHA | AT91C_SPI_BITS_8 }; -/* Card insertion verification.*/ -static bool_t mmc_is_inserted(void) { - return !palReadPad(IOPORT1, PIOA_MMC_CP); -} - -/* Card protection verification.*/ -static bool_t mmc_is_protected(void) { - return palReadPad(IOPORT1, PIOA_MMC_WP); -} +/* MMC/SD over SPI driver configuration.*/ +static MMCConfig mmccfg = {&SPID1, &ls_spicfg, &hs_spicfg}; /* Generic large buffer.*/ uint8_t fbuff[1024]; @@ -306,10 +299,8 @@ int main(void) { */ palSetPadMode(IOPORT1, PIOA_MMC_NPCS0, PAL_MODE_OUTPUT_PUSHPULL); palSetPad(IOPORT1, PIOA_MMC_NPCS0); - mmcObjectInit(&MMCD1, &SPID1, - &ls_spicfg, &hs_spicfg, - mmc_is_protected, mmc_is_inserted); - mmcStart(&MMCD1, NULL); + mmcObjectInit(&MMCD1); + mmcStart(&MMCD1, &mmccfg); /* * Creates the blinker threads. diff --git a/demos/ARM7-AT91SAM7X-FATFS-GCC/main.c b/demos/ARM7-AT91SAM7X-FATFS-GCC/main.c index 54bee4680..0b3f838fd 100644 --- a/demos/ARM7-AT91SAM7X-FATFS-GCC/main.c +++ b/demos/ARM7-AT91SAM7X-FATFS-GCC/main.c @@ -61,15 +61,8 @@ static SPIConfig ls_spicfg = { (MIN_SPI_BITRATE << 8) | AT91C_SPI_NCPHA | AT91C_SPI_BITS_8 }; -/* Card insertion verification.*/ -static bool_t mmc_is_inserted(void) { - return !palReadPad(IOPORT2, PIOB_MMC_CP); -} - -/* Card protection verification.*/ -static bool_t mmc_is_protected(void) { - return palReadPad(IOPORT2, PIOB_MMC_WP); -} +/* MMC/SD over SPI driver configuration.*/ +static MMCConfig mmccfg = {&SPID1, &ls_spicfg, &hs_spicfg}; /* Generic large buffer.*/ uint8_t fbuff[1024]; @@ -288,10 +281,8 @@ int main(void) { */ palSetPadMode(IOPORT1, PIOA_CS_MMC, PAL_MODE_OUTPUT_PUSHPULL); palSetPad(IOPORT1, PIOA_CS_MMC); - mmcObjectInit(&MMCD1, &SPID1, - &ls_spicfg, &hs_spicfg, - mmc_is_protected, mmc_is_inserted); - mmcStart(&MMCD1, NULL); + mmcObjectInit(&MMCD1); + mmcStart(&MMCD1, &mmccfg); /* * Creates the blinker threads. diff --git a/demos/ARM7-LPC214x-FATFS-GCC/main.c b/demos/ARM7-LPC214x-FATFS-GCC/main.c index d541e4899..1b3b86848 100644 --- a/demos/ARM7-LPC214x-FATFS-GCC/main.c +++ b/demos/ARM7-LPC214x-FATFS-GCC/main.c @@ -60,15 +60,8 @@ static SPIConfig ls_spicfg = { 254 }; -/* Card insertion verification.*/ -static bool_t mmc_is_inserted(void) { - return !palReadPad(IOPORT2, PB_CP1); -} - -/* Card protection verification.*/ -static bool_t mmc_is_protected(void) { - return palReadPad(IOPORT2, PB_WP1); -} +/* MMC/SD over SPI driver configuration.*/ +static MMCConfig mmccfg = {&SPID1, &ls_spicfg, &hs_spicfg}; /* Generic large buffer.*/ uint8_t fbuff[1024]; @@ -255,10 +248,8 @@ int main(void) { /* * Initializes the MMC driver to work with SPI2. */ - mmcObjectInit(&MMCD1, &SPID1, - &ls_spicfg, &hs_spicfg, - mmc_is_protected, mmc_is_inserted); - mmcStart(&MMCD1, NULL); + mmcObjectInit(&MMCD1); + mmcStart(&MMCD1, &mmccfg); /* * Creates the blinker threads. diff --git a/demos/ARMCM3-STM32F103-FATFS/main.c b/demos/ARMCM3-STM32F103-FATFS/main.c index 8df04aef7..16d04dd49 100644 --- a/demos/ARMCM3-STM32F103-FATFS/main.c +++ b/demos/ARMCM3-STM32F103-FATFS/main.c @@ -53,6 +53,9 @@ static SPIConfig hs_spicfg = {NULL, IOPORT2, GPIOB_SPI2NSS, 0}; static SPIConfig ls_spicfg = {NULL, IOPORT2, GPIOB_SPI2NSS, SPI_CR1_BR_2 | SPI_CR1_BR_1}; +/* MMC/SD over SPI driver configuration.*/ +static MMCConfig mmccfg = {&SPID2, &ls_spicfg, &hs_spicfg}; + /* Generic large buffer.*/ uint8_t fbuff[1024]; @@ -271,8 +274,8 @@ int main(void) { */ palSetPadMode(IOPORT2, GPIOB_SPI2NSS, PAL_MODE_OUTPUT_PUSHPULL); palSetPad(IOPORT2, GPIOB_SPI2NSS); - mmcObjectInit(&MMCD1, &SPID2, &ls_spicfg, &hs_spicfg); - mmcStart(&MMCD1, NULL); + mmcObjectInit(&MMCD1); + mmcStart(&MMCD1, &mmccfg); /* * Creates the blinker thread. diff --git a/demos/ARMCM3-STM32F103ZG-FATFS/main.c b/demos/ARMCM3-STM32F103ZG-FATFS/main.c index 8ce90f704..b21e7a864 100644 --- a/demos/ARMCM3-STM32F103ZG-FATFS/main.c +++ b/demos/ARMCM3-STM32F103ZG-FATFS/main.c @@ -227,7 +227,7 @@ static void cmd_tree(BaseSequentialStream *chp, int argc, char *argv[]) { chprintf(chp, "FS: %lu free clusters, %lu sectors per cluster, %lu bytes free\r\n", clusters, (uint32_t)SDC_FS.csize, - clusters * (uint32_t)SDC_FS.csize * (uint32_t)SDC_BLOCK_SIZE); + clusters * (uint32_t)SDC_FS.csize * (uint32_t)MMCSD_BLOCK_SIZE); fbuff[0] = 0; scan_files(chp, (char *)fbuff); } diff --git a/os/hal/hal.mk b/os/hal/hal.mk index 83cf1bd1b..b2eed900e 100644 --- a/os/hal/hal.mk +++ b/os/hal/hal.mk @@ -8,17 +8,18 @@ HALSRC = ${CHIBIOS}/os/hal/src/hal.c \ ${CHIBIOS}/os/hal/src/i2c.c \ ${CHIBIOS}/os/hal/src/icu.c \ ${CHIBIOS}/os/hal/src/mac.c \ + ${CHIBIOS}/os/hal/src/mmc_spi.c \ + ${CHIBIOS}/os/hal/src/mmcsd.c \ ${CHIBIOS}/os/hal/src/pal.c \ ${CHIBIOS}/os/hal/src/pwm.c \ + ${CHIBIOS}/os/hal/src/rtc.c \ ${CHIBIOS}/os/hal/src/sdc.c \ ${CHIBIOS}/os/hal/src/serial.c \ - ${CHIBIOS}/os/hal/src/spi.c \ - ${CHIBIOS}/os/hal/src/uart.c \ - ${CHIBIOS}/os/hal/src/usb.c \ - ${CHIBIOS}/os/hal/src/tm.c \ - ${CHIBIOS}/os/hal/src/mmc_spi.c \ ${CHIBIOS}/os/hal/src/serial_usb.c \ - ${CHIBIOS}/os/hal/src/rtc.c + ${CHIBIOS}/os/hal/src/spi.c \ + ${CHIBIOS}/os/hal/src/tm.c \ + ${CHIBIOS}/os/hal/src/uart.c \ + ${CHIBIOS}/os/hal/src/usb.c # Required include directories HALINC = ${CHIBIOS}/os/hal/include diff --git a/os/hal/include/mmc_spi.h b/os/hal/include/mmc_spi.h index 760ab3ad1..a5812e399 100644 --- a/os/hal/include/mmc_spi.h +++ b/os/hal/include/mmc_spi.h @@ -102,11 +102,21 @@ typedef enum { } mmcstate_t; /** - * @brief Driver configuration structure. - * @note Not required in the current implementation. + * @brief MMC/SD over SPI driver configuration structure. */ typedef struct { - uint8_t dummy; + /** + * @brief SPI driver associated to this MMC driver. + */ + SPIDriver *spip; + /** + * @brief SPI low speed configuration used during initialization. + */ + const SPIConfig *lscfg; + /** + * @brief SPI high speed configuration used during transfers. + */ + const SPIConfig *hscfg; } MMCConfig; /** @@ -127,18 +137,6 @@ typedef struct { * @brief Current configuration data. */ const MMCConfig *config; - /** - * @brief SPI driver associated to this MMC driver. - */ - SPIDriver *spip; - /** - * @brief SPI low speed configuration used during initialization. - */ - const SPIConfig *lscfg; - /** - * @brief SPI high speed configuration used during transfers. - */ - const SPIConfig *hscfg; /** * @brief Card insertion event source. */ @@ -200,8 +198,7 @@ typedef struct { extern "C" { #endif void mmcInit(void); - void mmcObjectInit(MMCDriver *mmcp, SPIDriver *spip, - const SPIConfig *lscfg, const SPIConfig *hscfg); + void mmcObjectInit(MMCDriver *mmcp); void mmcStart(MMCDriver *mmcp, const MMCConfig *config); void mmcStop(MMCDriver *mmcp); bool_t mmcConnect(MMCDriver *mmcp); diff --git a/os/hal/include/mmcsd.h b/os/hal/include/mmcsd.h index fbea45245..b21c29442 100644 --- a/os/hal/include/mmcsd.h +++ b/os/hal/include/mmcsd.h @@ -20,7 +20,7 @@ /** * @file mmcsd.h - * @brief MMC/SD cards header. + * @brief MMC/SD cards common header. * * @addtogroup MMCSD * @{ @@ -38,57 +38,121 @@ /** * @brief Fixed block size for MMC/SD block devices. */ -#define SDMMC_BLOCK_SIZE 512 +#define MMCSD_BLOCK_SIZE 512 /** * @brief Mask of error bits in R1 responses. */ -#define SDMMC_R1_ERROR_MASK 0xFDFFE008 +#define MMCSD_R1_ERROR_MASK 0xFDFFE008 /** * @brief Fixed pattern for CMD8. */ -#define SDMMC_CMD8_PATTERN 0x000001AA +#define MMCSD_CMD8_PATTERN 0x000001AA /** * @name SD/MMC status conditions * @{ */ -#define SDMMC_STS_IDLE 0 -#define SDMMC_STS_READY 1 -#define SDMMC_STS_IDENT 2 -#define SDMMC_STS_STBY 3 -#define SDMMC_STS_TRAN 4 -#define SDMMC_STS_DATA 5 -#define SDMMC_STS_RCV 6 -#define SDMMC_STS_PRG 7 -#define SDMMC_STS_DIS 8 +#define MMCSD_STS_IDLE 0 +#define MMCSD_STS_READY 1 +#define MMCSD_STS_IDENT 2 +#define MMCSD_STS_STBY 3 +#define MMCSD_STS_TRAN 4 +#define MMCSD_STS_DATA 5 +#define MMCSD_STS_RCV 6 +#define MMCSD_STS_PRG 7 +#define MMCSD_STS_DIS 8 /** @} */ /** * @name SD/MMC commands * @{ */ -#define SDMMC_CMD_GO_IDLE_STATE 0 -#define SDMMC_CMD_INIT 1 -#define SDMMC_CMD_ALL_SEND_CID 2 -#define SDMMC_CMD_SEND_RELATIVE_ADDR 3 -#define SDMMC_CMD_SET_BUS_WIDTH 6 -#define SDMMC_CMD_SEL_DESEL_CARD 7 -#define SDMMC_CMD_SEND_IF_COND 8 -#define SDMMC_CMD_SEND_CSD 9 -#define SDMMC_CMD_STOP_TRANSMISSION 12 -#define SDMMC_CMD_SEND_STATUS 13 -#define SDMMC_CMD_SET_BLOCKLEN 16 -#define SDMMC_CMD_READ_SINGLE_BLOCK 17 -#define SDMMC_CMD_READ_MULTIPLE_BLOCK 18 -#define SDMMC_CMD_SET_BLOCK_COUNT 23 -#define SDMMC_CMD_WRITE_BLOCK 24 -#define SDMMC_CMD_WRITE_MULTIPLE_BLOCK 25 -#define SDMMC_CMD_APP_OP_COND 41 -#define SDMMC_CMD_LOCK_UNLOCK 42 -#define SDMMC_CMD_APP_CMD 55 -#define SDMMC_CMD_READ_OCR 58 +#define MMCSD_CMD_GO_IDLE_STATE 0 +#define MMCSD_CMD_INIT 1 +#define MMCSD_CMD_ALL_SEND_CID 2 +#define MMCSD_CMD_SEND_RELATIVE_ADDR 3 +#define MMCSD_CMD_SET_BUS_WIDTH 6 +#define MMCSD_CMD_SEL_DESEL_CARD 7 +#define MMCSD_CMD_SEND_IF_COND 8 +#define MMCSD_CMD_SEND_CSD 9 +#define MMCSD_CMD_STOP_TRANSMISSION 12 +#define MMCSD_CMD_SEND_STATUS 13 +#define MMCSD_CMD_SET_BLOCKLEN 16 +#define MMCSD_CMD_READ_SINGLE_BLOCK 17 +#define MMCSD_CMD_READ_MULTIPLE_BLOCK 18 +#define MMCSD_CMD_SET_BLOCK_COUNT 23 +#define MMCSD_CMD_WRITE_BLOCK 24 +#define MMCSD_CMD_WRITE_MULTIPLE_BLOCK 25 +#define MMCSD_CMD_APP_OP_COND 41 +#define MMCSD_CMD_LOCK_UNLOCK 42 +#define MMCSD_CMD_APP_CMD 55 +#define MMCSD_CMD_READ_OCR 58 +/** @} */ + +/** + * @name CSD record offsets + */ +/** + * @brief Slice position of values in CSD register. + */ +/* CSD version 2.0 */ +#define MMCSD_CSD_20_CRC_SLICE 7,1 +#define MMCSD_CSD_20_FILE_FORMAT_SLICE 11,10 +#define MMCSD_CSD_20_TMP_WRITE_PROTECT_SLICE 12,12 +#define MMCSD_CSD_20_PERM_WRITE_PROTECT_SLICE 13,13 +#define MMCSD_CSD_20_COPY_SLICE 14,14 +#define MMCSD_CSD_20_FILE_FORMAT_GRP_SLICE 15,15 +#define MMCSD_CSD_20_WRITE_BL_PARTIAL_SLICE 21,21 +#define MMCSD_CSD_20_WRITE_BL_LEN_SLICE 25,12 +#define MMCSD_CSD_20_R2W_FACTOR_SLICE 28,26 +#define MMCSD_CSD_20_WP_GRP_ENABLE_SLICE 31,31 +#define MMCSD_CSD_20_WP_GRP_SIZE_SLICE 38,32 +#define MMCSD_CSD_20_ERASE_SECTOR_SIZE_SLICE 45,39 +#define MMCSD_CSD_20_ERASE_BLK_EN_SLICE 46,46 +#define MMCSD_CSD_20_C_SIZE_SLICE 69,48 +#define MMCSD_CSD_20_DSR_IMP_SLICE 76,76 +#define MMCSD_CSD_20_READ_BLK_MISALIGN_SLICE 77,77 +#define MMCSD_CSD_20_WRITE_BLK_MISALIGN_SLICE 78,78 +#define MMCSD_CSD_20_READ_BL_PARTIAL_SLICE 79,79 +#define MMCSD_CSD_20_READ_BL_LEN_SLICE 83,80 +#define MMCSD_CSD_20_CCC_SLICE 95,84 +#define MMCSD_CSD_20_TRANS_SPEED_SLICE 103,96 +#define MMCSD_CSD_20_NSAC_SLICE 111,104 +#define MMCSD_CSD_20_TAAC_SLICE 119,112 +#define MMCSD_CSD_20_STRUCTURE_SLICE 127,126 + +/* CSD version 1.0 */ +#define MMCSD_CSD_10_CRC_SLICE MMCSD_CSD_20_CRC_SLICE +#define MMCSD_CSD_10_FILE_FORMAT_SLICE MMCSD_CSD_20_FILE_FORMAT_SLICE +#define MMCSD_CSD_10_TMP_WRITE_PROTECT_SLICE MMCSD_CSD_20_TMP_WRITE_PROTECT_SLICE +#define MMCSD_CSD_10_PERM_WRITE_PROTECT_SLICE MMCSD_CSD_20_PERM_WRITE_PROTECT_SLICE +#define MMCSD_CSD_10_COPY_SLICE MMCSD_CSD_20_COPY_SLICE +#define MMCSD_CSD_10_FILE_FORMAT_GRP_SLICE MMCSD_CSD_20_FILE_FORMAT_GRP_SLICE +#define MMCSD_CSD_10_WRITE_BL_PARTIAL_SLICE MMCSD_CSD_20_WRITE_BL_PARTIAL_SLICE +#define MMCSD_CSD_10_WRITE_BL_LEN_SLICE MMCSD_CSD_20_WRITE_BL_LEN_SLICE +#define MMCSD_CSD_10_R2W_FACTOR_SLICE MMCSD_CSD_20_R2W_FACTOR_SLICE +#define MMCSD_CSD_10_WP_GRP_ENABLE_SLICE MMCSD_CSD_20_WP_GRP_ENABLE_SLICE +#define MMCSD_CSD_10_WP_GRP_SIZE_SLICE MMCSD_CSD_20_WP_GRP_SIZE_SLICE +#define MMCSD_CSD_10_ERASE_SECTOR_SIZE_SLICE MMCSD_CSD_20_ERASE_SECTOR_SIZE_SLICE +#define MMCSD_CSD_10_ERASE_BLK_EN_SLICE MMCSD_CSD_20_ERASE_BLK_EN_SLICE +#define MMCSD_CSD_10_C_SIZE_MULT_SLICE 49,47 +#define MMCSD_CSD_10_VDD_W_CURR_MAX_SLICE 52,50 +#define MMCSD_CSD_10_VDD_W_CURR_MIN_SLICE 55,53 +#define MMCSD_CSD_10_VDD_R_CURR_MAX_SLICE 58,56 +#define MMCSD_CSD_10_VDD_R_CURR_MIX_SLICE 61,59 +#define MMCSD_CSD_10_C_SIZE_SLICE 73,62 +#define MMCSD_CSD_10_DSR_IMP_SLICE MMCSD_CSD_20_DSR_IMP_SLICE +#define MMCSD_CSD_10_READ_BLK_MISALIGN_SLICE MMCSD_CSD_20_READ_BLK_MISALIGN_SLICE +#define MMCSD_CSD_10_WRITE_BLK_MISALIGN_SLICE MMCSD_CSD_20_WRITE_BLK_MISALIGN_SLICE +#define MMCSD_CSD_10_READ_BL_PARTIAL_SLICE MMCSD_CSD_20_READ_BL_PARTIAL_SLICE +#define MMCSD_CSD_10_READ_BL_LEN_SLICE 83, 80 +#define MMCSD_CSD_10_CCC_SLICE MMCSD_CSD_20_CCC_SLICE +#define MMCSD_CSD_10_TRANS_SPEED_SLICE MMCSD_CSD_20_TRANS_SPEED_SLICE +#define MMCSD_CSD_10_NSAC_SLICE MMCSD_CSD_20_NSAC_SLICE +#define MMCSD_CSD_10_TAAC_SLICE MMCSD_CSD_20_TAAC_SLICE +#define MMCSD_CSD_10_STRUCTURE_SLICE MMCSD_CSD_20_STRUCTURE_SLICE /** @} */ /*===========================================================================*/ @@ -149,6 +213,7 @@ typedef struct { #ifdef __cplusplus extern "C" { #endif + uint32_t mmcsdGetCapacity(uint32_t csd[4]); #ifdef __cplusplus } #endif diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h index 20c15c211..f54007f44 100644 --- a/os/hal/include/sdc.h +++ b/os/hal/include/sdc.h @@ -35,13 +35,6 @@ /* Driver constants. */ /*===========================================================================*/ -#define SDC_BLOCK_SIZE 512 /**< Fixed block size. */ - -/** - * @brief Fixed pattern for CMD8. - */ -#define SDC_CMD8_PATTERN 0x000001AA - /** * @name SD cart types * @{ @@ -53,54 +46,19 @@ #define SDC_MODE_HIGH_CAPACITY 0x10 /**< @brief High cap.card. */ /** @} */ -/** - * @brief Mask of error bits in R1 responses. - */ -#define SDC_R1_ERROR_MASK 0xFDFFE008 - -#define SDC_STS_IDLE 0 -#define SDC_STS_READY 1 -#define SDC_STS_IDENT 2 -#define SDC_STS_STBY 3 -#define SDC_STS_TRAN 4 -#define SDC_STS_DATA 5 -#define SDC_STS_RCV 6 -#define SDC_STS_PRG 7 -#define SDC_STS_DIS 8 - -#define SDC_CMD_GO_IDLE_STATE 0 -#define SDC_CMD_INIT 1 -#define SDC_CMD_ALL_SEND_CID 2 -#define SDC_CMD_SEND_RELATIVE_ADDR 3 -#define SDC_CMD_SET_BUS_WIDTH 6 -#define SDC_CMD_SEL_DESEL_CARD 7 -#define SDC_CMD_SEND_IF_COND 8 -#define SDC_CMD_SEND_CSD 9 -#define SDC_CMD_STOP_TRANSMISSION 12 -#define SDC_CMD_SEND_STATUS 13 -#define SDC_CMD_SET_BLOCKLEN 16 -#define SDC_CMD_READ_SINGLE_BLOCK 17 -#define SDC_CMD_READ_MULTIPLE_BLOCK 18 -#define SDC_CMD_SET_BLOCK_COUNT 23 -#define SDC_CMD_WRITE_BLOCK 24 -#define SDC_CMD_WRITE_MULTIPLE_BLOCK 25 -#define SDC_CMD_APP_OP_COND 41 -#define SDC_CMD_LOCK_UNLOCK 42 -#define SDC_CMD_APP_CMD 55 - /** * @name SDC bus error conditions * @{ */ -#define SDC_NO_ERROR 0 /**< @brief No error. */ -#define SDC_CMD_CRC_ERROR 1 /**< @brief Command CRC error. */ -#define SDC_DATA_CRC_ERROR 2 /**< @brief Data CRC error. */ -#define SDC_DATA_TIMEOUT 4 /**< @brief Hardware write timeout.*/ -#define SDC_COMMAND_TIMEOUT 8 /**< @brief Hardware read timeout. */ -#define SDC_TX_UNDERRUN 16 /**< @brief TX buffer underrun. */ -#define SDC_RX_OVERRUN 32 /**< @brief RX buffer overrun. */ -#define SDC_STARTBIT_ERROR 64 /**< @brief Start bit not detected.*/ -#define SDC_OVERFLOW_ERROR 128 /**< @brief Card overflow error. */ +#define SDC_NO_ERROR 0 /**< @brief No error. */ +#define SDC_CMD_CRC_ERROR 1 /**< @brief Command CRC error. */ +#define SDC_DATA_CRC_ERROR 2 /**< @brief Data CRC error. */ +#define SDC_DATA_TIMEOUT 4 /**< @brief HW write timeout. */ +#define SDC_COMMAND_TIMEOUT 8 /**< @brief HW read timeout. */ +#define SDC_TX_UNDERRUN 16 /**< @brief TX buffer underrun. */ +#define SDC_RX_OVERRUN 32 /**< @brief RX buffer overrun. */ +#define SDC_STARTBIT_ERROR 64 /**< @brief Start bit missing. */ +#define SDC_OVERFLOW_ERROR 128 /**< @brief Card overflow error. */ #define SDC_UNHANDLED_ERROR 0xFFFFFFFF /** @} */ @@ -168,32 +126,6 @@ typedef enum { /* Driver macros. */ /*===========================================================================*/ -/** - * @name R1 response utilities - * @{ - */ -/** - * @brief Evaluates to @p TRUE if the R1 response contains error flags. - * - * @param[in] r1 the r1 response - */ -#define SDC_R1_ERROR(r1) (((r1) & SDC_R1_ERROR_MASK) != 0) - -/** - * @brief Returns the status field of an R1 response. - * - * @param[in] r1 the r1 response - */ -#define SDC_R1_STS(r1) (((r1) >> 9) & 15) - -/** - * @brief Evaluates to @p TRUE if the R1 response indicates a locked card. - * - * @param[in] r1 the r1 response - */ -#define SDC_R1_IS_CARD_LOCKED(r1) (((r1) >> 21) & 1) -/** @} */ - /** * @name Macro Functions * @{ @@ -251,70 +183,6 @@ typedef enum { #define sdcGetCardCapacity(sdcp) ((sdcp)->capacity) /** @} */ -/** - * @name CSD record offsets - */ -/** - * @brief Slice position of values in CSD register. - */ -/* CSD version 2.0 */ -#define SDC_CSD_20_CRC_SLICE 7,1 -#define SDC_CSD_20_FILE_FORMAT_SLICE 11,10 -#define SDC_CSD_20_TMP_WRITE_PROTECT_SLICE 12,12 -#define SDC_CSD_20_PERM_WRITE_PROTECT_SLICE 13,13 -#define SDC_CSD_20_COPY_SLICE 14,14 -#define SDC_CSD_20_FILE_FORMAT_GRP_SLICE 15,15 -#define SDC_CSD_20_WRITE_BL_PARTIAL_SLICE 21,21 -#define SDC_CSD_20_WRITE_BL_LEN_SLICE 25,12 -#define SDC_CSD_20_R2W_FACTOR_SLICE 28,26 -#define SDC_CSD_20_WP_GRP_ENABLE_SLICE 31,31 -#define SDC_CSD_20_WP_GRP_SIZE_SLICE 38,32 -#define SDC_CSD_20_ERASE_SECTOR_SIZE_SLICE 45,39 -#define SDC_CSD_20_ERASE_BLK_EN_SLICE 46,46 -#define SDC_CSD_20_C_SIZE_SLICE 69,48 -#define SDC_CSD_20_DSR_IMP_SLICE 76,76 -#define SDC_CSD_20_READ_BLK_MISALIGN_SLICE 77,77 -#define SDC_CSD_20_WRITE_BLK_MISALIGN_SLICE 78,78 -#define SDC_CSD_20_READ_BL_PARTIAL_SLICE 79,79 -#define SDC_CSD_20_READ_BL_LEN_SLICE 83,80 -#define SDC_CSD_20_CCC_SLICE 95,84 -#define SDC_CSD_20_TRANS_SPEED_SLICE 103,96 -#define SDC_CSD_20_NSAC_SLICE 111,104 -#define SDC_CSD_20_TAAC_SLICE 119,112 -#define SDC_CSD_20_STRUCTURE_SLICE 127,126 - -/* CSD version 1.0 */ -#define SDC_CSD_10_CRC_SLICE SDC_CSD_20_CRC_SLICE -#define SDC_CSD_10_FILE_FORMAT_SLICE SDC_CSD_20_FILE_FORMAT_SLICE -#define SDC_CSD_10_TMP_WRITE_PROTECT_SLICE SDC_CSD_20_TMP_WRITE_PROTECT_SLICE -#define SDC_CSD_10_PERM_WRITE_PROTECT_SLICE SDC_CSD_20_PERM_WRITE_PROTECT_SLICE -#define SDC_CSD_10_COPY_SLICE SDC_CSD_20_COPY_SLICE -#define SDC_CSD_10_FILE_FORMAT_GRP_SLICE SDC_CSD_20_FILE_FORMAT_GRP_SLICE -#define SDC_CSD_10_WRITE_BL_PARTIAL_SLICE SDC_CSD_20_WRITE_BL_PARTIAL_SLICE -#define SDC_CSD_10_WRITE_BL_LEN_SLICE SDC_CSD_20_WRITE_BL_LEN_SLICE -#define SDC_CSD_10_R2W_FACTOR_SLICE SDC_CSD_20_R2W_FACTOR_SLICE -#define SDC_CSD_10_WP_GRP_ENABLE_SLICE SDC_CSD_20_WP_GRP_ENABLE_SLICE -#define SDC_CSD_10_WP_GRP_SIZE_SLICE SDC_CSD_20_WP_GRP_SIZE_SLICE -#define SDC_CSD_10_ERASE_SECTOR_SIZE_SLICE SDC_CSD_20_ERASE_SECTOR_SIZE_SLICE -#define SDC_CSD_10_ERASE_BLK_EN_SLICE SDC_CSD_20_ERASE_BLK_EN_SLICE -#define SDC_CSD_10_C_SIZE_MULT_SLICE 49,47 -#define SDC_CSD_10_VDD_W_CURR_MAX_SLICE 52,50 -#define SDC_CSD_10_VDD_W_CURR_MIN_SLICE 55,53 -#define SDC_CSD_10_VDD_R_CURR_MAX_SLICE 58,56 -#define SDC_CSD_10_VDD_R_CURR_MIX_SLICE 61,59 -#define SDC_CSD_10_C_SIZE_SLICE 73,62 -#define SDC_CSD_10_DSR_IMP_SLICE SDC_CSD_20_DSR_IMP_SLICE -#define SDC_CSD_10_READ_BLK_MISALIGN_SLICE SDC_CSD_20_READ_BLK_MISALIGN_SLICE -#define SDC_CSD_10_WRITE_BLK_MISALIGN_SLICE SDC_CSD_20_WRITE_BLK_MISALIGN_SLICE -#define SDC_CSD_10_READ_BL_PARTIAL_SLICE SDC_CSD_20_READ_BL_PARTIAL_SLICE -#define SDC_CSD_10_READ_BL_LEN_SLICE 83, 80 -#define SDC_CSD_10_CCC_SLICE SDC_CSD_20_CCC_SLICE -#define SDC_CSD_10_TRANS_SPEED_SLICE SDC_CSD_20_TRANS_SPEED_SLICE -#define SDC_CSD_10_NSAC_SLICE SDC_CSD_20_NSAC_SLICE -#define SDC_CSD_10_TAAC_SLICE SDC_CSD_20_TAAC_SLICE -#define SDC_CSD_10_STRUCTURE_SLICE SDC_CSD_20_STRUCTURE_SLICE -/** @} */ - /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/sdc_lld.c b/os/hal/platforms/STM32/sdc_lld.c index 1bc553baf..14752c049 100644 --- a/os/hal/platforms/STM32/sdc_lld.c +++ b/os/hal/platforms/STM32/sdc_lld.c @@ -62,7 +62,7 @@ SDCDriver SDCD1; */ static union { uint32_t alignment; - uint8_t buf[SDC_BLOCK_SIZE]; + uint8_t buf[MMCSD_BLOCK_SIZE]; } u; #endif /* STM32_SDC_SDIO_UNALIGNED_SUPPORT */ @@ -90,18 +90,18 @@ static bool_t sdc_lld_prepare_read(SDCDriver *sdcp, uint32_t startblk, /* Driver handles data in 512 bytes blocks (just like HC cards). But if we have not HC card than we must convert address from blocks to bytes.*/ if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY)) - startblk *= SDC_BLOCK_SIZE; + startblk *= MMCSD_BLOCK_SIZE; if (n > 1){ /* Send read multiple blocks command to card.*/ - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_MULTIPLE_BLOCK, - startblk, resp) || SDC_R1_ERROR(resp[0])) + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_READ_MULTIPLE_BLOCK, + startblk, resp) || MMCSD_R1_ERROR(resp[0])) return CH_FAILED; } else{ /* Send read single block command.*/ - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_SINGLE_BLOCK, - startblk, resp) || SDC_R1_ERROR(resp[0])) + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_READ_SINGLE_BLOCK, + startblk, resp) || MMCSD_R1_ERROR(resp[0])) return CH_FAILED; } @@ -128,18 +128,18 @@ static bool_t sdc_lld_prepare_write(SDCDriver *sdcp, uint32_t startblk, /* Driver handles data in 512 bytes blocks (just like HC cards). But if we have not HC card than we must convert address from blocks to bytes.*/ if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY)) - startblk *= SDC_BLOCK_SIZE; + startblk *= MMCSD_BLOCK_SIZE; if (n > 1){ /* Write multiple blocks command.*/ - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_MULTIPLE_BLOCK, - startblk, resp) || SDC_R1_ERROR(resp[0])) + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_WRITE_MULTIPLE_BLOCK, + startblk, resp) || MMCSD_R1_ERROR(resp[0])) return CH_FAILED; } else{ /* Write single block command.*/ - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_BLOCK, - startblk, resp) || SDC_R1_ERROR(resp[0])) + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_WRITE_BLOCK, + startblk, resp) || MMCSD_R1_ERROR(resp[0])) return CH_FAILED; } @@ -203,7 +203,7 @@ static bool_t sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n, /* Finalize transaction.*/ if (n > 1) - return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); + return sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp); return CH_SUCCESS; } @@ -270,7 +270,7 @@ static void sdc_lld_error_cleanup(SDCDriver *sdcp, SDIO->DCTRL = 0; sdc_lld_collect_errors(sdcp); if (n > 1) - sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); + sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_STOP_TRANSMISSION, 0, resp); } /*===========================================================================*/ @@ -604,7 +604,7 @@ bool_t sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk, uint8_t *buf, uint32_t n) { uint32_t resp[1]; - chDbgCheck((n < (0x1000000 / SDC_BLOCK_SIZE)), "max transaction size"); + chDbgCheck((n < (0x1000000 / MMCSD_BLOCK_SIZE)), "max transaction size"); SDIO->DTIMER = STM32_SDC_READ_TIMEOUT; @@ -615,7 +615,7 @@ bool_t sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk, /* Prepares the DMA channel for writing.*/ dmaStreamSetMemory0(sdcp->dma, buf); dmaStreamSetTransactionSize(sdcp->dma, - (n * SDC_BLOCK_SIZE) / sizeof (uint32_t)); + (n * MMCSD_BLOCK_SIZE) / sizeof (uint32_t)); dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M); dmaStreamEnable(sdcp->dma); @@ -626,7 +626,7 @@ bool_t sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk, SDIO_MASK_STBITERRIE | SDIO_MASK_RXOVERRIE | SDIO_MASK_DATAENDIE; - SDIO->DLEN = n * SDC_BLOCK_SIZE; + SDIO->DLEN = n * MMCSD_BLOCK_SIZE; /* Talk to card what we want from it.*/ if (sdc_lld_prepare_read(sdcp, startblk, n, resp) == TRUE) @@ -666,7 +666,7 @@ bool_t sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk, const uint8_t *buf, uint32_t n) { uint32_t resp[1]; - chDbgCheck((n < (0x1000000 / SDC_BLOCK_SIZE)), "max transaction size"); + chDbgCheck((n < (0x1000000 / MMCSD_BLOCK_SIZE)), "max transaction size"); SDIO->DTIMER = STM32_SDC_WRITE_TIMEOUT; @@ -677,7 +677,7 @@ bool_t sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk, /* Prepares the DMA channel for writing.*/ dmaStreamSetMemory0(sdcp->dma, buf); dmaStreamSetTransactionSize(sdcp->dma, - (n * SDC_BLOCK_SIZE) / sizeof (uint32_t)); + (n * MMCSD_BLOCK_SIZE) / sizeof (uint32_t)); dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_M2P); dmaStreamEnable(sdcp->dma); @@ -688,7 +688,7 @@ bool_t sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk, SDIO_MASK_STBITERRIE | SDIO_MASK_TXUNDERRIE | SDIO_MASK_DATAENDIE; - SDIO->DLEN = n * SDC_BLOCK_SIZE; + SDIO->DLEN = n * MMCSD_BLOCK_SIZE; /* Talk to card what we want from it.*/ if (sdc_lld_prepare_write(sdcp, startblk, n, resp) == TRUE) @@ -732,8 +732,8 @@ bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk, for (i = 0; i < n; i++) { if (sdc_lld_read_aligned(sdcp, startblk, u.buf, 1)) return CH_FAILED; - memcpy(buf, u.buf, SDC_BLOCK_SIZE); - buf += SDC_BLOCK_SIZE; + memcpy(buf, u.buf, MMCSD_BLOCK_SIZE); + buf += MMCSD_BLOCK_SIZE; startblk++; } return CH_SUCCESS; @@ -763,8 +763,8 @@ bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk, if (((unsigned)buf & 3) != 0) { uint32_t i; for (i = 0; i < n; i++) { - memcpy(u.buf, buf, SDC_BLOCK_SIZE); - buf += SDC_BLOCK_SIZE; + memcpy(u.buf, buf, MMCSD_BLOCK_SIZE); + buf += MMCSD_BLOCK_SIZE; if (sdc_lld_write_aligned(sdcp, startblk, u.buf, 1)) return CH_FAILED; startblk++; diff --git a/os/hal/platforms/STM32/sdc_lld.h b/os/hal/platforms/STM32/sdc_lld.h index 5d31827b4..b89ad2586 100644 --- a/os/hal/platforms/STM32/sdc_lld.h +++ b/os/hal/platforms/STM32/sdc_lld.h @@ -38,19 +38,19 @@ /** * @brief Value to clear all interrupts flag at once. */ -#define STM32_SDIO_ICR_ALL_FLAGS (SDIO_ICR_CCRCFAILC | SDIO_ICR_DCRCFAILC | \ - SDIO_ICR_CTIMEOUTC | SDIO_ICR_DTIMEOUTC | \ - SDIO_ICR_TXUNDERRC | SDIO_ICR_RXOVERRC | \ - SDIO_ICR_CMDRENDC | SDIO_ICR_CMDSENTC | \ - SDIO_ICR_DATAENDC | SDIO_ICR_STBITERRC | \ - SDIO_ICR_DBCKENDC | SDIO_ICR_SDIOITC | \ +#define STM32_SDIO_ICR_ALL_FLAGS (SDIO_ICR_CCRCFAILC | SDIO_ICR_DCRCFAILC | \ + SDIO_ICR_CTIMEOUTC | SDIO_ICR_DTIMEOUTC | \ + SDIO_ICR_TXUNDERRC | SDIO_ICR_RXOVERRC | \ + SDIO_ICR_CMDRENDC | SDIO_ICR_CMDSENTC | \ + SDIO_ICR_DATAENDC | SDIO_ICR_STBITERRC | \ + SDIO_ICR_DBCKENDC | SDIO_ICR_SDIOITC | \ SDIO_ICR_CEATAENDC) /** * @brief Mask of error flags in STA register. */ -#define STM32_SDIO_STA_ERROR_MASK (SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | \ - SDIO_STA_CTIMEOUT | SDIO_STA_DTIMEOUT | \ +#define STM32_SDIO_STA_ERROR_MASK (SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | \ + SDIO_STA_CTIMEOUT | SDIO_STA_DTIMEOUT | \ SDIO_STA_TXUNDERR | SDIO_STA_RXOVERR) /*===========================================================================*/ @@ -259,6 +259,32 @@ struct SDCDriver { /* Driver macros. */ /*===========================================================================*/ +/** + * @name R1 response utilities + * @{ + */ +/** + * @brief Evaluates to @p TRUE if the R1 response contains error flags. + * + * @param[in] r1 the r1 response + */ +#define MMCSD_R1_ERROR(r1) (((r1) & MMCSD_R1_ERROR_MASK) != 0) + +/** + * @brief Returns the status field of an R1 response. + * + * @param[in] r1 the r1 response + */ +#define MMCSD_R1_STS(r1) (((r1) >> 9) & 15) + +/** + * @brief Evaluates to @p TRUE if the R1 response indicates a locked card. + * + * @param[in] r1 the r1 response + */ +#define MMCSD_R1_IS_CARD_LOCKED(r1) (((r1) >> 21) & 1) +/** @} */ + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ diff --git a/os/hal/src/mmc_spi.c b/os/hal/src/mmc_spi.c index 97f4f271d..dad837613 100644 --- a/os/hal/src/mmc_spi.c +++ b/os/hal/src/mmc_spi.c @@ -108,7 +108,7 @@ bool_t mmc_read(void *instance, uint32_t startblk, while (n > 0) { if (mmcSequentialRead((MMCDriver *)instance, buffer)) return TRUE; - buffer += SDMMC_BLOCK_SIZE; + buffer += MMCSD_BLOCK_SIZE; n--; } if (mmcStopSequentialRead((MMCDriver *)instance)) @@ -124,7 +124,7 @@ bool_t mmc_write(void *instance, uint32_t startblk, while (n > 0) { if (mmcSequentialWrite((MMCDriver *)instance, buffer)) return TRUE; - buffer += SDMMC_BLOCK_SIZE; + buffer += MMCSD_BLOCK_SIZE; n--; } if (mmcStopSequentialWrite((MMCDriver *)instance)) @@ -191,13 +191,13 @@ static void wait(MMCDriver *mmcp) { uint8_t buf[4]; for (i = 0; i < 16; i++) { - spiReceive(mmcp->spip, 1, buf); + spiReceive(mmcp->config->spip, 1, buf); if (buf[0] == 0xFF) return; } /* Looks like it is a long wait.*/ while (TRUE) { - spiReceive(mmcp->spip, 1, buf); + spiReceive(mmcp->config->spip, 1, buf); if (buf[0] == 0xFF) break; #ifdef MMC_NICE_WAITING @@ -230,7 +230,7 @@ static void send_hdr(MMCDriver *mmcp, uint8_t cmd, uint32_t arg) { /* Calculate CRC for command header, shift to right position, add stop bit.*/ buf[5] = ((crc7(0, buf, 5) & 0x7F) << 1) | 0x01; - spiSend(mmcp->spip, 6, buf); + spiSend(mmcp->config->spip, 6, buf); } /** @@ -247,7 +247,7 @@ static uint8_t recvr1(MMCDriver *mmcp) { uint8_t r1[1]; for (i = 0; i < 9; i++) { - spiReceive(mmcp->spip, 1, r1); + spiReceive(mmcp->config->spip, 1, r1); if (r1[0] != 0xFF) return r1[0]; } @@ -268,7 +268,7 @@ static uint8_t recvr3(MMCDriver *mmcp, uint8_t* buffer) { uint8_t r1; r1 = recvr1(mmcp); - spiReceive(mmcp->spip, 4, buffer); + spiReceive(mmcp->config->spip, 4, buffer); return r1; } @@ -287,10 +287,10 @@ static uint8_t recvr3(MMCDriver *mmcp, uint8_t* buffer) { static uint8_t send_command_R1(MMCDriver *mmcp, uint8_t cmd, uint32_t arg) { uint8_t r1; - spiSelect(mmcp->spip); + spiSelect(mmcp->config->spip); send_hdr(mmcp, cmd, arg); r1 = recvr1(mmcp); - spiUnselect(mmcp->spip); + spiUnselect(mmcp->config->spip); return r1; } @@ -311,10 +311,10 @@ static uint8_t send_command_R3(MMCDriver *mmcp, uint8_t cmd, uint32_t arg, uint8_t *response) { uint8_t r1; - spiSelect(mmcp->spip); + spiSelect(mmcp->config->spip); send_hdr(mmcp, cmd, arg); r1 = recvr3(mmcp, response); - spiUnselect(mmcp->spip); + spiUnselect(mmcp->config->spip); return r1; } @@ -328,16 +328,16 @@ static uint8_t send_command_R3(MMCDriver *mmcp, uint8_t cmd, uint32_t arg, static void sync(MMCDriver *mmcp) { uint8_t buf[1]; - spiSelect(mmcp->spip); + spiSelect(mmcp->config->spip); while (TRUE) { - spiReceive(mmcp->spip, 1, buf); + spiReceive(mmcp->config->spip, 1, buf); if (buf[0] == 0xFF) break; #ifdef MMC_NICE_WAITING chThdSleep(1); /* Trying to be nice with the other threads.*/ #endif } - spiUnselect(mmcp->spip); + spiUnselect(mmcp->config->spip); } /*===========================================================================*/ @@ -369,15 +369,11 @@ void mmcInit(void) { * * @init */ -void mmcObjectInit(MMCDriver *mmcp, SPIDriver *spip, - const SPIConfig *lscfg, const SPIConfig *hscfg) { +void mmcObjectInit(MMCDriver *mmcp) { mmcp->vmt = &mmc_vmt; mmcp->state = MMC_STOP; mmcp->config = NULL; - mmcp->spip = spip; - mmcp->lscfg = lscfg; - mmcp->hscfg = hscfg; mmcp->block_addresses = FALSE; chEvtInit(&mmcp->inserted_event); chEvtInit(&mmcp->removed_event); @@ -425,7 +421,7 @@ void mmcStop(MMCDriver *mmcp) { chVTResetI(&mmcp->vt); } chSysUnlock(); - spiStop(mmcp->spip); + spiStop(mmcp->config->spip); } /** @@ -456,13 +452,13 @@ bool_t mmcConnect(MMCDriver *mmcp) { if (mmcp->state == MMC_INSERTED) { /* Slow clock mode and 128 clock pulses.*/ - spiStart(mmcp->spip, mmcp->lscfg); - spiIgnore(mmcp->spip, 16); + spiStart(mmcp->config->spip, mmcp->config->lscfg); + spiIgnore(mmcp->config->spip, 16); /* SPI mode selection.*/ i = 0; while (TRUE) { - if (send_command_R1(mmcp, SDMMC_CMD_GO_IDLE_STATE, 0) == 0x01) + if (send_command_R1(mmcp, MMCSD_CMD_GO_IDLE_STATE, 0) == 0x01) break; if (++i >= MMC_CMD0_RETRY) return TRUE; @@ -474,14 +470,14 @@ bool_t mmcConnect(MMCDriver *mmcp) { This method is based on "How to support SDC Ver2 and high capacity cards" by ElmChan.*/ uint8_t r3[4]; - if (send_command_R3(mmcp, SDMMC_CMD_SEND_IF_COND, - SDMMC_CMD8_PATTERN, r3) != 0x05) { + if (send_command_R3(mmcp, MMCSD_CMD_SEND_IF_COND, + MMCSD_CMD8_PATTERN, r3) != 0x05) { /* Switch to SDHC mode.*/ i = 0; while (TRUE) { - if ((send_command_R1(mmcp, SDMMC_CMD_APP_CMD, 0) == 0x01) && - (send_command_R3(mmcp, SDMMC_CMD_APP_OP_COND, + if ((send_command_R1(mmcp, MMCSD_CMD_APP_CMD, 0) == 0x01) && + (send_command_R3(mmcp, MMCSD_CMD_APP_OP_COND, 0x400001aa, r3) == 0x00)) break; @@ -491,7 +487,7 @@ bool_t mmcConnect(MMCDriver *mmcp) { } /* Execute dedicated read on OCR register */ - send_command_R3(mmcp, SDMMC_CMD_READ_OCR, 0, r3); + send_command_R3(mmcp, MMCSD_CMD_READ_OCR, 0, r3); /* Check if CCS is set in response. Card operates in block mode if set.*/ if(r3[0] & 0x40) @@ -501,7 +497,7 @@ bool_t mmcConnect(MMCDriver *mmcp) { /* Initialization.*/ i = 0; while (TRUE) { - uint8_t b = send_command_R1(mmcp, SDMMC_CMD_INIT, 0); + uint8_t b = send_command_R1(mmcp, MMCSD_CMD_INIT, 0); if (b == 0x00) break; if (b != 0x01) @@ -512,11 +508,11 @@ bool_t mmcConnect(MMCDriver *mmcp) { } /* Initialization complete, full speed.*/ - spiStart(mmcp->spip, mmcp->hscfg); + spiStart(mmcp->config->spip, mmcp->config->hscfg); /* Setting block size.*/ - if (send_command_R1(mmcp, SDMMC_CMD_SET_BLOCKLEN, - SDMMC_BLOCK_SIZE) != 0x00) + if (send_command_R1(mmcp, MMCSD_CMD_SET_BLOCKLEN, + MMCSD_BLOCK_SIZE) != 0x00) return TRUE; /* Transition to MMC_READY state (if not extracted).*/ @@ -568,7 +564,7 @@ bool_t mmcDisconnect(MMCDriver *mmcp) { default: status = TRUE; } - spiStop(mmcp->spip); + spiStop(mmcp->config->spip); return status; } @@ -596,16 +592,16 @@ bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk) { mmcp->state = MMC_READING; chSysUnlock(); - spiStart(mmcp->spip, mmcp->hscfg); - spiSelect(mmcp->spip); + spiStart(mmcp->config->spip, mmcp->config->hscfg); + spiSelect(mmcp->config->spip); if(mmcp->block_addresses) - send_hdr(mmcp, SDMMC_CMD_READ_MULTIPLE_BLOCK, startblk); + send_hdr(mmcp, MMCSD_CMD_READ_MULTIPLE_BLOCK, startblk); else - send_hdr(mmcp, SDMMC_CMD_READ_MULTIPLE_BLOCK, startblk * SDMMC_BLOCK_SIZE); + send_hdr(mmcp, MMCSD_CMD_READ_MULTIPLE_BLOCK, startblk * MMCSD_BLOCK_SIZE); if (recvr1(mmcp) != 0x00) { - spiUnselect(mmcp->spip); + spiUnselect(mmcp->config->spip); chSysLock(); if (mmcp->state == MMC_READING) mmcp->state = MMC_READY; @@ -640,16 +636,16 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) { chSysUnlock(); for (i = 0; i < MMC_WAIT_DATA; i++) { - spiReceive(mmcp->spip, 1, buffer); + spiReceive(mmcp->config->spip, 1, buffer); if (buffer[0] == 0xFE) { - spiReceive(mmcp->spip, SDMMC_BLOCK_SIZE, buffer); + spiReceive(mmcp->config->spip, MMCSD_BLOCK_SIZE, buffer); /* CRC ignored. */ - spiIgnore(mmcp->spip, 2); + spiIgnore(mmcp->config->spip, 2); return FALSE; } } /* Timeout.*/ - spiUnselect(mmcp->spip); + spiUnselect(mmcp->config->spip); chSysLock(); if (mmcp->state == MMC_READING) mmcp->state = MMC_READY; @@ -669,7 +665,7 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) { * @api */ bool_t mmcStopSequentialRead(MMCDriver *mmcp) { - static const uint8_t stopcmd[] = {0x40 | SDMMC_CMD_STOP_TRANSMISSION, + static const uint8_t stopcmd[] = {0x40 | MMCSD_CMD_STOP_TRANSMISSION, 0, 0, 0, 0, 1, 0xFF}; bool_t result; @@ -682,12 +678,12 @@ bool_t mmcStopSequentialRead(MMCDriver *mmcp) { } chSysUnlock(); - spiSend(mmcp->spip, sizeof(stopcmd), stopcmd); + spiSend(mmcp->config->spip, sizeof(stopcmd), stopcmd); /* result = recvr1(mmcp) != 0x00;*/ /* Note, ignored r1 response, it can be not zero, unknown issue.*/ recvr1(mmcp); result = FALSE; - spiUnselect(mmcp->spip); + spiUnselect(mmcp->config->spip); chSysLock(); if (mmcp->state == MMC_READING) @@ -720,17 +716,17 @@ bool_t mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk) { mmcp->state = MMC_WRITING; chSysUnlock(); - spiStart(mmcp->spip, mmcp->hscfg); - spiSelect(mmcp->spip); + spiStart(mmcp->config->spip, mmcp->config->hscfg); + spiSelect(mmcp->config->spip); if(mmcp->block_addresses) - send_hdr(mmcp, SDMMC_CMD_WRITE_MULTIPLE_BLOCK, startblk); + send_hdr(mmcp, MMCSD_CMD_WRITE_MULTIPLE_BLOCK, startblk); else - send_hdr(mmcp, SDMMC_CMD_WRITE_MULTIPLE_BLOCK, - startblk * SDMMC_BLOCK_SIZE); + send_hdr(mmcp, MMCSD_CMD_WRITE_MULTIPLE_BLOCK, + startblk * MMCSD_BLOCK_SIZE); if (recvr1(mmcp) != 0x00) { - spiUnselect(mmcp->spip); + spiUnselect(mmcp->config->spip); chSysLock(); if (mmcp->state == MMC_WRITING) mmcp->state = MMC_READY; @@ -765,17 +761,17 @@ bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) { } chSysUnlock(); - spiSend(mmcp->spip, sizeof(start), start); /* Data prologue. */ - spiSend(mmcp->spip, SDMMC_BLOCK_SIZE, buffer); /* Data. */ - spiIgnore(mmcp->spip, 2); /* CRC ignored. */ - spiReceive(mmcp->spip, 1, b); + spiSend(mmcp->config->spip, sizeof(start), start); /* Data prologue. */ + spiSend(mmcp->config->spip, MMCSD_BLOCK_SIZE, buffer);/* Data. */ + spiIgnore(mmcp->config->spip, 2); /* CRC ignored. */ + spiReceive(mmcp->config->spip, 1, b); if ((b[0] & 0x1F) == 0x05) { wait(mmcp); return FALSE; } /* Error.*/ - spiUnselect(mmcp->spip); + spiUnselect(mmcp->config->spip); chSysLock(); if (mmcp->state == MMC_WRITING) mmcp->state = MMC_READY; @@ -806,8 +802,8 @@ bool_t mmcStopSequentialWrite(MMCDriver *mmcp) { } chSysUnlock(); - spiSend(mmcp->spip, sizeof(stop), stop); - spiUnselect(mmcp->spip); + spiSend(mmcp->config->spip, sizeof(stop), stop); + spiUnselect(mmcp->config->spip); chSysLock(); if (mmcp->state == MMC_WRITING) { @@ -871,7 +867,7 @@ bool_t mmcGetInfo(MMCDriver *mmcp, BlockDeviceInfo *bdip) { chSysUnlock(); bdip->blk_num = 0; /* NOTE: To be implemented.*/ - bdip->blk_size = SDMMC_BLOCK_SIZE; + bdip->blk_size = MMCSD_BLOCK_SIZE; return FALSE; } diff --git a/os/hal/src/mmcsd.c b/os/hal/src/mmcsd.c new file mode 100644 index 000000000..88f8a5505 --- /dev/null +++ b/os/hal/src/mmcsd.c @@ -0,0 +1,120 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file mmcsd.c + * @brief MMC/SD cards common code. + * + * @addtogroup MMCSD + * @{ + */ + +#include "ch.h" +#include "hal.h" + +#if HAL_USE_MMC_SPI || HAL_USE_SDC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Get slice with data from uint32_t[4] array. + * + * @notapi + */ +static uint32_t mmcsd_get_slice(uint32_t *data, uint32_t end, uint32_t start) { + uint32_t word = 0; + uint32_t mask = 0; + + chDbgCheck(end >= start, "sdc_get_slice"); + + while ((start - 32 * word) > 31){ + word++; + data++; + } + + end -= 32 * word; + start -= 32 * word; + + if (end < 31){ + /* Value lays in one word.*/ + mask = (1 << (end - start + 1)) - 1; + return (*data >> start) & mask; + } + else{ + /* Value spread on separate words.*/ + uint32_t lsb, msb; + lsb = *data >> start; + data++; + mask = (1 << (end - 32 + 1)) - 1; + msb = *data & mask; + msb = msb << (32 - start); + return msb | lsb; + } +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Extract card capacity from a CSD. + * @details The capacity is returned as number of available blocks. + * + * @param[in] csd the CSD record + * + * @return The card capacity. + * @retval 0 CSD format error + */ +uint32_t mmcsdGetCapacity(uint32_t csd[4]) { + + switch (csd[3] >> 30) { + uint32_t a, b, c; + case 0: + /* CSD version 1.0 */ + a = mmcsd_get_slice(csd, MMCSD_CSD_10_C_SIZE_SLICE); + b = mmcsd_get_slice(csd, MMCSD_CSD_10_C_SIZE_MULT_SLICE); + c = mmcsd_get_slice(csd, MMCSD_CSD_10_READ_BL_LEN_SLICE); + return (a + 1) << (b + 2) << (c - 9); /* 2^9 == MMCSD_BLOCK_SIZE. */ + case 1: + /* CSD version 2.0.*/ + return 1024 * (mmcsd_get_slice(csd, MMCSD_CSD_20_C_SIZE_SLICE) + 1); + default: + /* Reserved value detected.*/ + return 0; + } +} + +#endif /* HAL_USE_MMC_SPI || HAL_USE_SDC */ + +/** @} */ diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index 483263776..3ff938f98 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -61,42 +61,6 @@ static const struct MMCSDBlockDeviceVMT sdc_vmt = { /* Driver local functions. */ /*===========================================================================*/ -/** - * @brief Get slice with data from uint32_t[4] array. - * - * @notapi - */ -static uint32_t _sdc_get_slice(uint32_t *data, int32_t end, int32_t start) { - uint32_t word = 0; - uint32_t mask = 0; - - chDbgCheck(((start >=0) && (end >=0) && (end >= start)), "sdc_get_slice"); - - while ((start - 32 * word) > 31){ - word++; - data++; - } - - end -= 32 * word; - start -= 32 * word; - - if (end < 31){ - /* Value lays in one word.*/ - mask = (1 << (end - start + 1)) - 1; - return (*data >> start) & mask; - } - else{ - /* Value spread on separate words.*/ - uint32_t lsb, msb; - lsb = *data >> start; - data++; - mask = (1 << (end - 32 + 1)) - 1; - msb = *data & mask; - msb = msb << (32 - start); - return (msb | lsb); - } -} - /** * @brief Wait for the card to complete pending operations. * @@ -112,16 +76,16 @@ bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp) { uint32_t resp[1]; while (TRUE) { - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_STATUS, + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SEND_STATUS, sdcp->rca, resp) || - SDC_R1_ERROR(resp[0])) + MMCSD_R1_ERROR(resp[0])) return CH_FAILED; - switch (SDC_R1_STS(resp[0])) { - case SDC_STS_TRAN: + switch (MMCSD_R1_STS(resp[0])) { + case MMCSD_STS_TRAN: return CH_SUCCESS; - case SDC_STS_DATA: - case SDC_STS_RCV: - case SDC_STS_PRG: + case MMCSD_STS_DATA: + case MMCSD_STS_RCV: + case MMCSD_STS_PRG: #if SDC_NICE_WAITING chThdSleepMilliseconds(1); #endif @@ -239,23 +203,23 @@ bool_t sdcConnect(SDCDriver *sdcp) { sdc_lld_start_clk(sdcp); /* Enforces the initial card state.*/ - sdc_lld_send_cmd_none(sdcp, SDC_CMD_GO_IDLE_STATE, 0); + sdc_lld_send_cmd_none(sdcp, MMCSD_CMD_GO_IDLE_STATE, 0); /* V2.0 cards detection.*/ - if (!sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_IF_COND, - SDC_CMD8_PATTERN, resp)) { + if (!sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SEND_IF_COND, + MMCSD_CMD8_PATTERN, resp)) { sdcp->cardmode = SDC_MODE_CARDTYPE_SDV20; /* Voltage verification.*/ if (((resp[0] >> 8) & 0xF) != 1) goto failed; - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) || - SDC_R1_ERROR(resp[0])) + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_APP_CMD, 0, resp) || + MMCSD_R1_ERROR(resp[0])) goto failed; } else { #if SDC_MMC_SUPPORT /* MMC or SD V1.1 detection.*/ - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) || + if (sdc_lld_send_cmd_short_crc(sdcp, SDMMC_CMD_APP_CMD, 0, resp) || SDC_R1_ERROR(resp[0])) sdcp->cardmode = SDC_MODE_CARDTYPE_MMC; else @@ -283,10 +247,10 @@ bool_t sdcConnect(SDCDriver *sdcp) { /* SD-type initialization. */ i = 0; while (TRUE) { - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) || - SDC_R1_ERROR(resp[0])) + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_APP_CMD, 0, resp) || + MMCSD_R1_ERROR(resp[0])) goto failed; - if (sdc_lld_send_cmd_short(sdcp, SDC_CMD_APP_OP_COND, ocr, resp)) + if (sdc_lld_send_cmd_short(sdcp, MMCSD_CMD_APP_OP_COND, ocr, resp)) goto failed; if ((resp[0] & 0x80000000) != 0) { if (resp[0] & 0x40000000) @@ -300,30 +264,31 @@ bool_t sdcConnect(SDCDriver *sdcp) { } /* Reads CID.*/ - if (sdc_lld_send_cmd_long_crc(sdcp, SDC_CMD_ALL_SEND_CID, 0, sdcp->cid)) + if (sdc_lld_send_cmd_long_crc(sdcp, MMCSD_CMD_ALL_SEND_CID, 0, sdcp->cid)) goto failed; /* Asks for the RCA.*/ - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_RELATIVE_ADDR, + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SEND_RELATIVE_ADDR, 0, &sdcp->rca)) goto failed; /* Reads CSD.*/ - if (sdc_lld_send_cmd_long_crc(sdcp, SDC_CMD_SEND_CSD, sdcp->rca, sdcp->csd)) + if (sdc_lld_send_cmd_long_crc(sdcp, MMCSD_CMD_SEND_CSD, + sdcp->rca, sdcp->csd)) goto failed; /* Switches to high speed.*/ sdc_lld_set_data_clk(sdcp); /* Selects the card for operations.*/ - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEL_DESEL_CARD, + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SEL_DESEL_CARD, sdcp->rca, resp)) goto failed; /* Block length fixed at 512 bytes.*/ - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SET_BLOCKLEN, - SDC_BLOCK_SIZE, resp) || - SDC_R1_ERROR(resp[0])) + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SET_BLOCKLEN, + MMCSD_BLOCK_SIZE, resp) || + MMCSD_R1_ERROR(resp[0])) goto failed; /* Switches to wide bus mode.*/ @@ -331,35 +296,17 @@ bool_t sdcConnect(SDCDriver *sdcp) { case SDC_MODE_CARDTYPE_SDV11: case SDC_MODE_CARDTYPE_SDV20: sdc_lld_set_bus_mode(sdcp, SDC_MODE_4BIT); - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, sdcp->rca, resp) || - SDC_R1_ERROR(resp[0])) + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_APP_CMD, sdcp->rca, resp) || + MMCSD_R1_ERROR(resp[0])) goto failed; - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SET_BUS_WIDTH, 2, resp) || - SDC_R1_ERROR(resp[0])) + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SET_BUS_WIDTH, 2, resp) || + MMCSD_R1_ERROR(resp[0])) goto failed; break; } /* Determine capacity.*/ - switch (sdcp->csd[3] >> 30) { - uint32_t a, b, c; - case 0: - /* CSD version 1.0 */ - a = _sdc_get_slice(sdcp->csd, SDC_CSD_10_C_SIZE_SLICE); - b = _sdc_get_slice(sdcp->csd, SDC_CSD_10_C_SIZE_MULT_SLICE); - c = _sdc_get_slice(sdcp->csd, SDC_CSD_10_READ_BL_LEN_SLICE); - sdcp->capacity = ((a + 1) << (b + 2) << c) / 512; - break; - case 1: - /* CSD version 2.0 */ - a = _sdc_get_slice(sdcp->csd, SDC_CSD_20_C_SIZE_SLICE); - sdcp->capacity = 1024 * (a + 1); - break; - default: - /* Reserved value detected. */ - sdcp->capacity = 0; - break; - } + sdcp->capacity = mmcsdGetCapacity(sdcp->csd); if (sdcp->capacity == 0) goto failed; @@ -553,7 +500,7 @@ bool_t sdcGetInfo(SDCDriver *sdcp, BlockDeviceInfo *bdip) { chSysUnlock(); bdip->blk_num = 0; /* NOTE: To be implemented.*/ - bdip->blk_size = SDMMC_BLOCK_SIZE; + bdip->blk_size = MMCSD_BLOCK_SIZE; return FALSE; } diff --git a/os/various/fatfs_bindings/fatfs_diskio.c b/os/various/fatfs_bindings/fatfs_diskio.c index 07d44db49..06ee81acc 100644 --- a/os/various/fatfs_bindings/fatfs_diskio.c +++ b/os/various/fatfs_bindings/fatfs_diskio.c @@ -219,7 +219,7 @@ DRESULT disk_ioctl ( *((DWORD *)buff) = sdcGetCardCapacity(&SDCD1); return RES_OK; case GET_SECTOR_SIZE: - *((WORD *)buff) = SDC_BLOCK_SIZE; + *((WORD *)buff) = MMCSD_BLOCK_SIZE; return RES_OK; case GET_BLOCK_SIZE: *((DWORD *)buff) = 256; /* 512b blocks in one erase block */ diff --git a/readme.txt b/readme.txt index 4ad7cb722..adb92a450 100644 --- a/readme.txt +++ b/readme.txt @@ -123,11 +123,14 @@ 3484947)(backported to 2.4.1). - FIX: Fixed various minor documentation errors (bug 3484942)(backported to 2.4.1). +- NEW: Added a common ancestor class to the SDC and MMC_SPI drivers. This + allows to share code and definitions. - NEW: Modified the SDC driver to implement the new block devices abstract interface. - NEW: Added two new functions to the MMC_SPI driver: mmcSync() and mmc_Get_Info(). Also implemented the new block devices abstract - interface. + interface. Moved the configuration parameters from mmcObjectInit() to + the configuration structure saving some RAM space. Updated demos. - NEW: Added an abstract interface for block devices in the HAL. This abstraction layer is meant to unify the access protocol to the SDC and MMC_SPI (and potentially others) device drivers.