git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4180 35acf78f-673a-0410-8e92-d51de3d6d3f4

master
gdisirio 2012-05-10 12:26:24 +00:00
parent 6a8a643ab0
commit 97dce7b944
19 changed files with 458 additions and 414 deletions

View File

@ -65,6 +65,21 @@ void __early_init(void) {
lpc214x_clock_init(); 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. * Board-specific initialization code.
*/ */

View File

@ -74,6 +74,21 @@ void __early_init(void) {
at91sam7_clock_init(); 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. * Board-specific initialization code.
*/ */

View File

@ -68,6 +68,21 @@ void __early_init(void) {
at91sam7_clock_init(); 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. * Board-specific initialization code.
*/ */

View File

@ -61,15 +61,8 @@ static SPIConfig ls_spicfg = {
(MIN_SPI_BITRATE << 8) | AT91C_SPI_NCPHA | AT91C_SPI_BITS_8 (MIN_SPI_BITRATE << 8) | AT91C_SPI_NCPHA | AT91C_SPI_BITS_8
}; };
/* Card insertion verification.*/ /* MMC/SD over SPI driver configuration.*/
static bool_t mmc_is_inserted(void) { static MMCConfig mmccfg = {&SPID1, &ls_spicfg, &hs_spicfg};
return !palReadPad(IOPORT1, PIOA_MMC_CP);
}
/* Card protection verification.*/
static bool_t mmc_is_protected(void) {
return palReadPad(IOPORT1, PIOA_MMC_WP);
}
/* Generic large buffer.*/ /* Generic large buffer.*/
uint8_t fbuff[1024]; uint8_t fbuff[1024];
@ -306,10 +299,8 @@ int main(void) {
*/ */
palSetPadMode(IOPORT1, PIOA_MMC_NPCS0, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(IOPORT1, PIOA_MMC_NPCS0, PAL_MODE_OUTPUT_PUSHPULL);
palSetPad(IOPORT1, PIOA_MMC_NPCS0); palSetPad(IOPORT1, PIOA_MMC_NPCS0);
mmcObjectInit(&MMCD1, &SPID1, mmcObjectInit(&MMCD1);
&ls_spicfg, &hs_spicfg, mmcStart(&MMCD1, &mmccfg);
mmc_is_protected, mmc_is_inserted);
mmcStart(&MMCD1, NULL);
/* /*
* Creates the blinker threads. * Creates the blinker threads.

View File

@ -61,15 +61,8 @@ static SPIConfig ls_spicfg = {
(MIN_SPI_BITRATE << 8) | AT91C_SPI_NCPHA | AT91C_SPI_BITS_8 (MIN_SPI_BITRATE << 8) | AT91C_SPI_NCPHA | AT91C_SPI_BITS_8
}; };
/* Card insertion verification.*/ /* MMC/SD over SPI driver configuration.*/
static bool_t mmc_is_inserted(void) { static MMCConfig mmccfg = {&SPID1, &ls_spicfg, &hs_spicfg};
return !palReadPad(IOPORT2, PIOB_MMC_CP);
}
/* Card protection verification.*/
static bool_t mmc_is_protected(void) {
return palReadPad(IOPORT2, PIOB_MMC_WP);
}
/* Generic large buffer.*/ /* Generic large buffer.*/
uint8_t fbuff[1024]; uint8_t fbuff[1024];
@ -288,10 +281,8 @@ int main(void) {
*/ */
palSetPadMode(IOPORT1, PIOA_CS_MMC, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(IOPORT1, PIOA_CS_MMC, PAL_MODE_OUTPUT_PUSHPULL);
palSetPad(IOPORT1, PIOA_CS_MMC); palSetPad(IOPORT1, PIOA_CS_MMC);
mmcObjectInit(&MMCD1, &SPID1, mmcObjectInit(&MMCD1);
&ls_spicfg, &hs_spicfg, mmcStart(&MMCD1, &mmccfg);
mmc_is_protected, mmc_is_inserted);
mmcStart(&MMCD1, NULL);
/* /*
* Creates the blinker threads. * Creates the blinker threads.

View File

@ -60,15 +60,8 @@ static SPIConfig ls_spicfg = {
254 254
}; };
/* Card insertion verification.*/ /* MMC/SD over SPI driver configuration.*/
static bool_t mmc_is_inserted(void) { static MMCConfig mmccfg = {&SPID1, &ls_spicfg, &hs_spicfg};
return !palReadPad(IOPORT2, PB_CP1);
}
/* Card protection verification.*/
static bool_t mmc_is_protected(void) {
return palReadPad(IOPORT2, PB_WP1);
}
/* Generic large buffer.*/ /* Generic large buffer.*/
uint8_t fbuff[1024]; uint8_t fbuff[1024];
@ -255,10 +248,8 @@ int main(void) {
/* /*
* Initializes the MMC driver to work with SPI2. * Initializes the MMC driver to work with SPI2.
*/ */
mmcObjectInit(&MMCD1, &SPID1, mmcObjectInit(&MMCD1);
&ls_spicfg, &hs_spicfg, mmcStart(&MMCD1, &mmccfg);
mmc_is_protected, mmc_is_inserted);
mmcStart(&MMCD1, NULL);
/* /*
* Creates the blinker threads. * Creates the blinker threads.

View File

@ -53,6 +53,9 @@ static SPIConfig hs_spicfg = {NULL, IOPORT2, GPIOB_SPI2NSS, 0};
static SPIConfig ls_spicfg = {NULL, IOPORT2, GPIOB_SPI2NSS, static SPIConfig ls_spicfg = {NULL, IOPORT2, GPIOB_SPI2NSS,
SPI_CR1_BR_2 | SPI_CR1_BR_1}; 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.*/ /* Generic large buffer.*/
uint8_t fbuff[1024]; uint8_t fbuff[1024];
@ -271,8 +274,8 @@ int main(void) {
*/ */
palSetPadMode(IOPORT2, GPIOB_SPI2NSS, PAL_MODE_OUTPUT_PUSHPULL); palSetPadMode(IOPORT2, GPIOB_SPI2NSS, PAL_MODE_OUTPUT_PUSHPULL);
palSetPad(IOPORT2, GPIOB_SPI2NSS); palSetPad(IOPORT2, GPIOB_SPI2NSS);
mmcObjectInit(&MMCD1, &SPID2, &ls_spicfg, &hs_spicfg); mmcObjectInit(&MMCD1);
mmcStart(&MMCD1, NULL); mmcStart(&MMCD1, &mmccfg);
/* /*
* Creates the blinker thread. * Creates the blinker thread.

View File

@ -227,7 +227,7 @@ static void cmd_tree(BaseSequentialStream *chp, int argc, char *argv[]) {
chprintf(chp, chprintf(chp,
"FS: %lu free clusters, %lu sectors per cluster, %lu bytes free\r\n", "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,
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; fbuff[0] = 0;
scan_files(chp, (char *)fbuff); scan_files(chp, (char *)fbuff);
} }

View File

@ -8,17 +8,18 @@ HALSRC = ${CHIBIOS}/os/hal/src/hal.c \
${CHIBIOS}/os/hal/src/i2c.c \ ${CHIBIOS}/os/hal/src/i2c.c \
${CHIBIOS}/os/hal/src/icu.c \ ${CHIBIOS}/os/hal/src/icu.c \
${CHIBIOS}/os/hal/src/mac.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/pal.c \
${CHIBIOS}/os/hal/src/pwm.c \ ${CHIBIOS}/os/hal/src/pwm.c \
${CHIBIOS}/os/hal/src/rtc.c \
${CHIBIOS}/os/hal/src/sdc.c \ ${CHIBIOS}/os/hal/src/sdc.c \
${CHIBIOS}/os/hal/src/serial.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/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 # Required include directories
HALINC = ${CHIBIOS}/os/hal/include HALINC = ${CHIBIOS}/os/hal/include

View File

@ -102,11 +102,21 @@ typedef enum {
} mmcstate_t; } mmcstate_t;
/** /**
* @brief Driver configuration structure. * @brief MMC/SD over SPI driver configuration structure.
* @note Not required in the current implementation.
*/ */
typedef struct { 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; } MMCConfig;
/** /**
@ -127,18 +137,6 @@ typedef struct {
* @brief Current configuration data. * @brief Current configuration data.
*/ */
const MMCConfig *config; 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. * @brief Card insertion event source.
*/ */
@ -200,8 +198,7 @@ typedef struct {
extern "C" { extern "C" {
#endif #endif
void mmcInit(void); void mmcInit(void);
void mmcObjectInit(MMCDriver *mmcp, SPIDriver *spip, void mmcObjectInit(MMCDriver *mmcp);
const SPIConfig *lscfg, const SPIConfig *hscfg);
void mmcStart(MMCDriver *mmcp, const MMCConfig *config); void mmcStart(MMCDriver *mmcp, const MMCConfig *config);
void mmcStop(MMCDriver *mmcp); void mmcStop(MMCDriver *mmcp);
bool_t mmcConnect(MMCDriver *mmcp); bool_t mmcConnect(MMCDriver *mmcp);

View File

@ -20,7 +20,7 @@
/** /**
* @file mmcsd.h * @file mmcsd.h
* @brief MMC/SD cards header. * @brief MMC/SD cards common header.
* *
* @addtogroup MMCSD * @addtogroup MMCSD
* @{ * @{
@ -38,57 +38,121 @@
/** /**
* @brief Fixed block size for MMC/SD block devices. * @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. * @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. * @brief Fixed pattern for CMD8.
*/ */
#define SDMMC_CMD8_PATTERN 0x000001AA #define MMCSD_CMD8_PATTERN 0x000001AA
/** /**
* @name SD/MMC status conditions * @name SD/MMC status conditions
* @{ * @{
*/ */
#define SDMMC_STS_IDLE 0 #define MMCSD_STS_IDLE 0
#define SDMMC_STS_READY 1 #define MMCSD_STS_READY 1
#define SDMMC_STS_IDENT 2 #define MMCSD_STS_IDENT 2
#define SDMMC_STS_STBY 3 #define MMCSD_STS_STBY 3
#define SDMMC_STS_TRAN 4 #define MMCSD_STS_TRAN 4
#define SDMMC_STS_DATA 5 #define MMCSD_STS_DATA 5
#define SDMMC_STS_RCV 6 #define MMCSD_STS_RCV 6
#define SDMMC_STS_PRG 7 #define MMCSD_STS_PRG 7
#define SDMMC_STS_DIS 8 #define MMCSD_STS_DIS 8
/** @} */ /** @} */
/** /**
* @name SD/MMC commands * @name SD/MMC commands
* @{ * @{
*/ */
#define SDMMC_CMD_GO_IDLE_STATE 0 #define MMCSD_CMD_GO_IDLE_STATE 0
#define SDMMC_CMD_INIT 1 #define MMCSD_CMD_INIT 1
#define SDMMC_CMD_ALL_SEND_CID 2 #define MMCSD_CMD_ALL_SEND_CID 2
#define SDMMC_CMD_SEND_RELATIVE_ADDR 3 #define MMCSD_CMD_SEND_RELATIVE_ADDR 3
#define SDMMC_CMD_SET_BUS_WIDTH 6 #define MMCSD_CMD_SET_BUS_WIDTH 6
#define SDMMC_CMD_SEL_DESEL_CARD 7 #define MMCSD_CMD_SEL_DESEL_CARD 7
#define SDMMC_CMD_SEND_IF_COND 8 #define MMCSD_CMD_SEND_IF_COND 8
#define SDMMC_CMD_SEND_CSD 9 #define MMCSD_CMD_SEND_CSD 9
#define SDMMC_CMD_STOP_TRANSMISSION 12 #define MMCSD_CMD_STOP_TRANSMISSION 12
#define SDMMC_CMD_SEND_STATUS 13 #define MMCSD_CMD_SEND_STATUS 13
#define SDMMC_CMD_SET_BLOCKLEN 16 #define MMCSD_CMD_SET_BLOCKLEN 16
#define SDMMC_CMD_READ_SINGLE_BLOCK 17 #define MMCSD_CMD_READ_SINGLE_BLOCK 17
#define SDMMC_CMD_READ_MULTIPLE_BLOCK 18 #define MMCSD_CMD_READ_MULTIPLE_BLOCK 18
#define SDMMC_CMD_SET_BLOCK_COUNT 23 #define MMCSD_CMD_SET_BLOCK_COUNT 23
#define SDMMC_CMD_WRITE_BLOCK 24 #define MMCSD_CMD_WRITE_BLOCK 24
#define SDMMC_CMD_WRITE_MULTIPLE_BLOCK 25 #define MMCSD_CMD_WRITE_MULTIPLE_BLOCK 25
#define SDMMC_CMD_APP_OP_COND 41 #define MMCSD_CMD_APP_OP_COND 41
#define SDMMC_CMD_LOCK_UNLOCK 42 #define MMCSD_CMD_LOCK_UNLOCK 42
#define SDMMC_CMD_APP_CMD 55 #define MMCSD_CMD_APP_CMD 55
#define SDMMC_CMD_READ_OCR 58 #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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
uint32_t mmcsdGetCapacity(uint32_t csd[4]);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -35,13 +35,6 @@
/* Driver constants. */ /* Driver constants. */
/*===========================================================================*/ /*===========================================================================*/
#define SDC_BLOCK_SIZE 512 /**< Fixed block size. */
/**
* @brief Fixed pattern for CMD8.
*/
#define SDC_CMD8_PATTERN 0x000001AA
/** /**
* @name SD cart types * @name SD cart types
* @{ * @{
@ -53,54 +46,19 @@
#define SDC_MODE_HIGH_CAPACITY 0x10 /**< @brief High cap.card. */ #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 * @name SDC bus error conditions
* @{ * @{
*/ */
#define SDC_NO_ERROR 0 /**< @brief No error. */ #define SDC_NO_ERROR 0 /**< @brief No error. */
#define SDC_CMD_CRC_ERROR 1 /**< @brief Command CRC error. */ #define SDC_CMD_CRC_ERROR 1 /**< @brief Command CRC error. */
#define SDC_DATA_CRC_ERROR 2 /**< @brief Data CRC error. */ #define SDC_DATA_CRC_ERROR 2 /**< @brief Data CRC error. */
#define SDC_DATA_TIMEOUT 4 /**< @brief Hardware write timeout.*/ #define SDC_DATA_TIMEOUT 4 /**< @brief HW write timeout. */
#define SDC_COMMAND_TIMEOUT 8 /**< @brief Hardware read timeout. */ #define SDC_COMMAND_TIMEOUT 8 /**< @brief HW read timeout. */
#define SDC_TX_UNDERRUN 16 /**< @brief TX buffer underrun. */ #define SDC_TX_UNDERRUN 16 /**< @brief TX buffer underrun. */
#define SDC_RX_OVERRUN 32 /**< @brief RX buffer overrun. */ #define SDC_RX_OVERRUN 32 /**< @brief RX buffer overrun. */
#define SDC_STARTBIT_ERROR 64 /**< @brief Start bit not detected.*/ #define SDC_STARTBIT_ERROR 64 /**< @brief Start bit missing. */
#define SDC_OVERFLOW_ERROR 128 /**< @brief Card overflow error. */ #define SDC_OVERFLOW_ERROR 128 /**< @brief Card overflow error. */
#define SDC_UNHANDLED_ERROR 0xFFFFFFFF #define SDC_UNHANDLED_ERROR 0xFFFFFFFF
/** @} */ /** @} */
@ -168,32 +126,6 @@ typedef enum {
/* Driver macros. */ /* 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 * @name Macro Functions
* @{ * @{
@ -251,70 +183,6 @@ typedef enum {
#define sdcGetCardCapacity(sdcp) ((sdcp)->capacity) #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. */ /* External declarations. */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -62,7 +62,7 @@ SDCDriver SDCD1;
*/ */
static union { static union {
uint32_t alignment; uint32_t alignment;
uint8_t buf[SDC_BLOCK_SIZE]; uint8_t buf[MMCSD_BLOCK_SIZE];
} u; } u;
#endif /* STM32_SDC_SDIO_UNALIGNED_SUPPORT */ #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 /* 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.*/ have not HC card than we must convert address from blocks to bytes.*/
if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY)) if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY))
startblk *= SDC_BLOCK_SIZE; startblk *= MMCSD_BLOCK_SIZE;
if (n > 1){ if (n > 1){
/* Send read multiple blocks command to card.*/ /* Send read multiple blocks command to card.*/
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_MULTIPLE_BLOCK, if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_READ_MULTIPLE_BLOCK,
startblk, resp) || SDC_R1_ERROR(resp[0])) startblk, resp) || MMCSD_R1_ERROR(resp[0]))
return CH_FAILED; return CH_FAILED;
} }
else{ else{
/* Send read single block command.*/ /* Send read single block command.*/
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_SINGLE_BLOCK, if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_READ_SINGLE_BLOCK,
startblk, resp) || SDC_R1_ERROR(resp[0])) startblk, resp) || MMCSD_R1_ERROR(resp[0]))
return CH_FAILED; 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 /* 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.*/ have not HC card than we must convert address from blocks to bytes.*/
if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY)) if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY))
startblk *= SDC_BLOCK_SIZE; startblk *= MMCSD_BLOCK_SIZE;
if (n > 1){ if (n > 1){
/* Write multiple blocks command.*/ /* Write multiple blocks command.*/
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_MULTIPLE_BLOCK, if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_WRITE_MULTIPLE_BLOCK,
startblk, resp) || SDC_R1_ERROR(resp[0])) startblk, resp) || MMCSD_R1_ERROR(resp[0]))
return CH_FAILED; return CH_FAILED;
} }
else{ else{
/* Write single block command.*/ /* Write single block command.*/
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_BLOCK, if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_WRITE_BLOCK,
startblk, resp) || SDC_R1_ERROR(resp[0])) startblk, resp) || MMCSD_R1_ERROR(resp[0]))
return CH_FAILED; return CH_FAILED;
} }
@ -203,7 +203,7 @@ static bool_t sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n,
/* Finalize transaction.*/ /* Finalize transaction.*/
if (n > 1) 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; return CH_SUCCESS;
} }
@ -270,7 +270,7 @@ static void sdc_lld_error_cleanup(SDCDriver *sdcp,
SDIO->DCTRL = 0; SDIO->DCTRL = 0;
sdc_lld_collect_errors(sdcp); sdc_lld_collect_errors(sdcp);
if (n > 1) 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) { uint8_t *buf, uint32_t n) {
uint32_t resp[1]; 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; 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.*/ /* Prepares the DMA channel for writing.*/
dmaStreamSetMemory0(sdcp->dma, buf); dmaStreamSetMemory0(sdcp->dma, buf);
dmaStreamSetTransactionSize(sdcp->dma, 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); dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M);
dmaStreamEnable(sdcp->dma); dmaStreamEnable(sdcp->dma);
@ -626,7 +626,7 @@ bool_t sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk,
SDIO_MASK_STBITERRIE | SDIO_MASK_STBITERRIE |
SDIO_MASK_RXOVERRIE | SDIO_MASK_RXOVERRIE |
SDIO_MASK_DATAENDIE; SDIO_MASK_DATAENDIE;
SDIO->DLEN = n * SDC_BLOCK_SIZE; SDIO->DLEN = n * MMCSD_BLOCK_SIZE;
/* Talk to card what we want from it.*/ /* Talk to card what we want from it.*/
if (sdc_lld_prepare_read(sdcp, startblk, n, resp) == TRUE) 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) { const uint8_t *buf, uint32_t n) {
uint32_t resp[1]; 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; 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.*/ /* Prepares the DMA channel for writing.*/
dmaStreamSetMemory0(sdcp->dma, buf); dmaStreamSetMemory0(sdcp->dma, buf);
dmaStreamSetTransactionSize(sdcp->dma, 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); dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_M2P);
dmaStreamEnable(sdcp->dma); dmaStreamEnable(sdcp->dma);
@ -688,7 +688,7 @@ bool_t sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk,
SDIO_MASK_STBITERRIE | SDIO_MASK_STBITERRIE |
SDIO_MASK_TXUNDERRIE | SDIO_MASK_TXUNDERRIE |
SDIO_MASK_DATAENDIE; SDIO_MASK_DATAENDIE;
SDIO->DLEN = n * SDC_BLOCK_SIZE; SDIO->DLEN = n * MMCSD_BLOCK_SIZE;
/* Talk to card what we want from it.*/ /* Talk to card what we want from it.*/
if (sdc_lld_prepare_write(sdcp, startblk, n, resp) == TRUE) 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++) { for (i = 0; i < n; i++) {
if (sdc_lld_read_aligned(sdcp, startblk, u.buf, 1)) if (sdc_lld_read_aligned(sdcp, startblk, u.buf, 1))
return CH_FAILED; return CH_FAILED;
memcpy(buf, u.buf, SDC_BLOCK_SIZE); memcpy(buf, u.buf, MMCSD_BLOCK_SIZE);
buf += SDC_BLOCK_SIZE; buf += MMCSD_BLOCK_SIZE;
startblk++; startblk++;
} }
return CH_SUCCESS; return CH_SUCCESS;
@ -763,8 +763,8 @@ bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
if (((unsigned)buf & 3) != 0) { if (((unsigned)buf & 3) != 0) {
uint32_t i; uint32_t i;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
memcpy(u.buf, buf, SDC_BLOCK_SIZE); memcpy(u.buf, buf, MMCSD_BLOCK_SIZE);
buf += SDC_BLOCK_SIZE; buf += MMCSD_BLOCK_SIZE;
if (sdc_lld_write_aligned(sdcp, startblk, u.buf, 1)) if (sdc_lld_write_aligned(sdcp, startblk, u.buf, 1))
return CH_FAILED; return CH_FAILED;
startblk++; startblk++;

View File

@ -38,19 +38,19 @@
/** /**
* @brief Value to clear all interrupts flag at once. * @brief Value to clear all interrupts flag at once.
*/ */
#define STM32_SDIO_ICR_ALL_FLAGS (SDIO_ICR_CCRCFAILC | SDIO_ICR_DCRCFAILC | \ #define STM32_SDIO_ICR_ALL_FLAGS (SDIO_ICR_CCRCFAILC | SDIO_ICR_DCRCFAILC | \
SDIO_ICR_CTIMEOUTC | SDIO_ICR_DTIMEOUTC | \ SDIO_ICR_CTIMEOUTC | SDIO_ICR_DTIMEOUTC | \
SDIO_ICR_TXUNDERRC | SDIO_ICR_RXOVERRC | \ SDIO_ICR_TXUNDERRC | SDIO_ICR_RXOVERRC | \
SDIO_ICR_CMDRENDC | SDIO_ICR_CMDSENTC | \ SDIO_ICR_CMDRENDC | SDIO_ICR_CMDSENTC | \
SDIO_ICR_DATAENDC | SDIO_ICR_STBITERRC | \ SDIO_ICR_DATAENDC | SDIO_ICR_STBITERRC | \
SDIO_ICR_DBCKENDC | SDIO_ICR_SDIOITC | \ SDIO_ICR_DBCKENDC | SDIO_ICR_SDIOITC | \
SDIO_ICR_CEATAENDC) SDIO_ICR_CEATAENDC)
/** /**
* @brief Mask of error flags in STA register. * @brief Mask of error flags in STA register.
*/ */
#define STM32_SDIO_STA_ERROR_MASK (SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | \ #define STM32_SDIO_STA_ERROR_MASK (SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | \
SDIO_STA_CTIMEOUT | SDIO_STA_DTIMEOUT | \ SDIO_STA_CTIMEOUT | SDIO_STA_DTIMEOUT | \
SDIO_STA_TXUNDERR | SDIO_STA_RXOVERR) SDIO_STA_TXUNDERR | SDIO_STA_RXOVERR)
/*===========================================================================*/ /*===========================================================================*/
@ -259,6 +259,32 @@ struct SDCDriver {
/* Driver macros. */ /* 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. */ /* External declarations. */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -108,7 +108,7 @@ bool_t mmc_read(void *instance, uint32_t startblk,
while (n > 0) { while (n > 0) {
if (mmcSequentialRead((MMCDriver *)instance, buffer)) if (mmcSequentialRead((MMCDriver *)instance, buffer))
return TRUE; return TRUE;
buffer += SDMMC_BLOCK_SIZE; buffer += MMCSD_BLOCK_SIZE;
n--; n--;
} }
if (mmcStopSequentialRead((MMCDriver *)instance)) if (mmcStopSequentialRead((MMCDriver *)instance))
@ -124,7 +124,7 @@ bool_t mmc_write(void *instance, uint32_t startblk,
while (n > 0) { while (n > 0) {
if (mmcSequentialWrite((MMCDriver *)instance, buffer)) if (mmcSequentialWrite((MMCDriver *)instance, buffer))
return TRUE; return TRUE;
buffer += SDMMC_BLOCK_SIZE; buffer += MMCSD_BLOCK_SIZE;
n--; n--;
} }
if (mmcStopSequentialWrite((MMCDriver *)instance)) if (mmcStopSequentialWrite((MMCDriver *)instance))
@ -191,13 +191,13 @@ static void wait(MMCDriver *mmcp) {
uint8_t buf[4]; uint8_t buf[4];
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
spiReceive(mmcp->spip, 1, buf); spiReceive(mmcp->config->spip, 1, buf);
if (buf[0] == 0xFF) if (buf[0] == 0xFF)
return; return;
} }
/* Looks like it is a long wait.*/ /* Looks like it is a long wait.*/
while (TRUE) { while (TRUE) {
spiReceive(mmcp->spip, 1, buf); spiReceive(mmcp->config->spip, 1, buf);
if (buf[0] == 0xFF) if (buf[0] == 0xFF)
break; break;
#ifdef MMC_NICE_WAITING #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.*/ /* Calculate CRC for command header, shift to right position, add stop bit.*/
buf[5] = ((crc7(0, buf, 5) & 0x7F) << 1) | 0x01; 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]; uint8_t r1[1];
for (i = 0; i < 9; i++) { for (i = 0; i < 9; i++) {
spiReceive(mmcp->spip, 1, r1); spiReceive(mmcp->config->spip, 1, r1);
if (r1[0] != 0xFF) if (r1[0] != 0xFF)
return r1[0]; return r1[0];
} }
@ -268,7 +268,7 @@ static uint8_t recvr3(MMCDriver *mmcp, uint8_t* buffer) {
uint8_t r1; uint8_t r1;
r1 = recvr1(mmcp); r1 = recvr1(mmcp);
spiReceive(mmcp->spip, 4, buffer); spiReceive(mmcp->config->spip, 4, buffer);
return r1; 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) { static uint8_t send_command_R1(MMCDriver *mmcp, uint8_t cmd, uint32_t arg) {
uint8_t r1; uint8_t r1;
spiSelect(mmcp->spip); spiSelect(mmcp->config->spip);
send_hdr(mmcp, cmd, arg); send_hdr(mmcp, cmd, arg);
r1 = recvr1(mmcp); r1 = recvr1(mmcp);
spiUnselect(mmcp->spip); spiUnselect(mmcp->config->spip);
return r1; 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 *response) {
uint8_t r1; uint8_t r1;
spiSelect(mmcp->spip); spiSelect(mmcp->config->spip);
send_hdr(mmcp, cmd, arg); send_hdr(mmcp, cmd, arg);
r1 = recvr3(mmcp, response); r1 = recvr3(mmcp, response);
spiUnselect(mmcp->spip); spiUnselect(mmcp->config->spip);
return r1; 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) { static void sync(MMCDriver *mmcp) {
uint8_t buf[1]; uint8_t buf[1];
spiSelect(mmcp->spip); spiSelect(mmcp->config->spip);
while (TRUE) { while (TRUE) {
spiReceive(mmcp->spip, 1, buf); spiReceive(mmcp->config->spip, 1, buf);
if (buf[0] == 0xFF) if (buf[0] == 0xFF)
break; break;
#ifdef MMC_NICE_WAITING #ifdef MMC_NICE_WAITING
chThdSleep(1); /* Trying to be nice with the other threads.*/ chThdSleep(1); /* Trying to be nice with the other threads.*/
#endif #endif
} }
spiUnselect(mmcp->spip); spiUnselect(mmcp->config->spip);
} }
/*===========================================================================*/ /*===========================================================================*/
@ -369,15 +369,11 @@ void mmcInit(void) {
* *
* @init * @init
*/ */
void mmcObjectInit(MMCDriver *mmcp, SPIDriver *spip, void mmcObjectInit(MMCDriver *mmcp) {
const SPIConfig *lscfg, const SPIConfig *hscfg) {
mmcp->vmt = &mmc_vmt; mmcp->vmt = &mmc_vmt;
mmcp->state = MMC_STOP; mmcp->state = MMC_STOP;
mmcp->config = NULL; mmcp->config = NULL;
mmcp->spip = spip;
mmcp->lscfg = lscfg;
mmcp->hscfg = hscfg;
mmcp->block_addresses = FALSE; mmcp->block_addresses = FALSE;
chEvtInit(&mmcp->inserted_event); chEvtInit(&mmcp->inserted_event);
chEvtInit(&mmcp->removed_event); chEvtInit(&mmcp->removed_event);
@ -425,7 +421,7 @@ void mmcStop(MMCDriver *mmcp) {
chVTResetI(&mmcp->vt); chVTResetI(&mmcp->vt);
} }
chSysUnlock(); chSysUnlock();
spiStop(mmcp->spip); spiStop(mmcp->config->spip);
} }
/** /**
@ -456,13 +452,13 @@ bool_t mmcConnect(MMCDriver *mmcp) {
if (mmcp->state == MMC_INSERTED) { if (mmcp->state == MMC_INSERTED) {
/* Slow clock mode and 128 clock pulses.*/ /* Slow clock mode and 128 clock pulses.*/
spiStart(mmcp->spip, mmcp->lscfg); spiStart(mmcp->config->spip, mmcp->config->lscfg);
spiIgnore(mmcp->spip, 16); spiIgnore(mmcp->config->spip, 16);
/* SPI mode selection.*/ /* SPI mode selection.*/
i = 0; i = 0;
while (TRUE) { 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; break;
if (++i >= MMC_CMD0_RETRY) if (++i >= MMC_CMD0_RETRY)
return TRUE; 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" This method is based on "How to support SDC Ver2 and high capacity cards"
by ElmChan.*/ by ElmChan.*/
uint8_t r3[4]; uint8_t r3[4];
if (send_command_R3(mmcp, SDMMC_CMD_SEND_IF_COND, if (send_command_R3(mmcp, MMCSD_CMD_SEND_IF_COND,
SDMMC_CMD8_PATTERN, r3) != 0x05) { MMCSD_CMD8_PATTERN, r3) != 0x05) {
/* Switch to SDHC mode.*/ /* Switch to SDHC mode.*/
i = 0; i = 0;
while (TRUE) { while (TRUE) {
if ((send_command_R1(mmcp, SDMMC_CMD_APP_CMD, 0) == 0x01) && if ((send_command_R1(mmcp, MMCSD_CMD_APP_CMD, 0) == 0x01) &&
(send_command_R3(mmcp, SDMMC_CMD_APP_OP_COND, (send_command_R3(mmcp, MMCSD_CMD_APP_OP_COND,
0x400001aa, r3) == 0x00)) 0x400001aa, r3) == 0x00))
break; break;
@ -491,7 +487,7 @@ bool_t mmcConnect(MMCDriver *mmcp) {
} }
/* Execute dedicated read on OCR register */ /* 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.*/ /* Check if CCS is set in response. Card operates in block mode if set.*/
if(r3[0] & 0x40) if(r3[0] & 0x40)
@ -501,7 +497,7 @@ bool_t mmcConnect(MMCDriver *mmcp) {
/* Initialization.*/ /* Initialization.*/
i = 0; i = 0;
while (TRUE) { 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) if (b == 0x00)
break; break;
if (b != 0x01) if (b != 0x01)
@ -512,11 +508,11 @@ bool_t mmcConnect(MMCDriver *mmcp) {
} }
/* Initialization complete, full speed.*/ /* Initialization complete, full speed.*/
spiStart(mmcp->spip, mmcp->hscfg); spiStart(mmcp->config->spip, mmcp->config->hscfg);
/* Setting block size.*/ /* Setting block size.*/
if (send_command_R1(mmcp, SDMMC_CMD_SET_BLOCKLEN, if (send_command_R1(mmcp, MMCSD_CMD_SET_BLOCKLEN,
SDMMC_BLOCK_SIZE) != 0x00) MMCSD_BLOCK_SIZE) != 0x00)
return TRUE; return TRUE;
/* Transition to MMC_READY state (if not extracted).*/ /* Transition to MMC_READY state (if not extracted).*/
@ -568,7 +564,7 @@ bool_t mmcDisconnect(MMCDriver *mmcp) {
default: default:
status = TRUE; status = TRUE;
} }
spiStop(mmcp->spip); spiStop(mmcp->config->spip);
return status; return status;
} }
@ -596,16 +592,16 @@ bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk) {
mmcp->state = MMC_READING; mmcp->state = MMC_READING;
chSysUnlock(); chSysUnlock();
spiStart(mmcp->spip, mmcp->hscfg); spiStart(mmcp->config->spip, mmcp->config->hscfg);
spiSelect(mmcp->spip); spiSelect(mmcp->config->spip);
if(mmcp->block_addresses) if(mmcp->block_addresses)
send_hdr(mmcp, SDMMC_CMD_READ_MULTIPLE_BLOCK, startblk); send_hdr(mmcp, MMCSD_CMD_READ_MULTIPLE_BLOCK, startblk);
else 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) { if (recvr1(mmcp) != 0x00) {
spiUnselect(mmcp->spip); spiUnselect(mmcp->config->spip);
chSysLock(); chSysLock();
if (mmcp->state == MMC_READING) if (mmcp->state == MMC_READING)
mmcp->state = MMC_READY; mmcp->state = MMC_READY;
@ -640,16 +636,16 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) {
chSysUnlock(); chSysUnlock();
for (i = 0; i < MMC_WAIT_DATA; i++) { for (i = 0; i < MMC_WAIT_DATA; i++) {
spiReceive(mmcp->spip, 1, buffer); spiReceive(mmcp->config->spip, 1, buffer);
if (buffer[0] == 0xFE) { if (buffer[0] == 0xFE) {
spiReceive(mmcp->spip, SDMMC_BLOCK_SIZE, buffer); spiReceive(mmcp->config->spip, MMCSD_BLOCK_SIZE, buffer);
/* CRC ignored. */ /* CRC ignored. */
spiIgnore(mmcp->spip, 2); spiIgnore(mmcp->config->spip, 2);
return FALSE; return FALSE;
} }
} }
/* Timeout.*/ /* Timeout.*/
spiUnselect(mmcp->spip); spiUnselect(mmcp->config->spip);
chSysLock(); chSysLock();
if (mmcp->state == MMC_READING) if (mmcp->state == MMC_READING)
mmcp->state = MMC_READY; mmcp->state = MMC_READY;
@ -669,7 +665,7 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) {
* @api * @api
*/ */
bool_t mmcStopSequentialRead(MMCDriver *mmcp) { 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}; 0, 0, 0, 0, 1, 0xFF};
bool_t result; bool_t result;
@ -682,12 +678,12 @@ bool_t mmcStopSequentialRead(MMCDriver *mmcp) {
} }
chSysUnlock(); chSysUnlock();
spiSend(mmcp->spip, sizeof(stopcmd), stopcmd); spiSend(mmcp->config->spip, sizeof(stopcmd), stopcmd);
/* result = recvr1(mmcp) != 0x00;*/ /* result = recvr1(mmcp) != 0x00;*/
/* Note, ignored r1 response, it can be not zero, unknown issue.*/ /* Note, ignored r1 response, it can be not zero, unknown issue.*/
recvr1(mmcp); recvr1(mmcp);
result = FALSE; result = FALSE;
spiUnselect(mmcp->spip); spiUnselect(mmcp->config->spip);
chSysLock(); chSysLock();
if (mmcp->state == MMC_READING) if (mmcp->state == MMC_READING)
@ -720,17 +716,17 @@ bool_t mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk) {
mmcp->state = MMC_WRITING; mmcp->state = MMC_WRITING;
chSysUnlock(); chSysUnlock();
spiStart(mmcp->spip, mmcp->hscfg); spiStart(mmcp->config->spip, mmcp->config->hscfg);
spiSelect(mmcp->spip); spiSelect(mmcp->config->spip);
if(mmcp->block_addresses) if(mmcp->block_addresses)
send_hdr(mmcp, SDMMC_CMD_WRITE_MULTIPLE_BLOCK, startblk); send_hdr(mmcp, MMCSD_CMD_WRITE_MULTIPLE_BLOCK, startblk);
else else
send_hdr(mmcp, SDMMC_CMD_WRITE_MULTIPLE_BLOCK, send_hdr(mmcp, MMCSD_CMD_WRITE_MULTIPLE_BLOCK,
startblk * SDMMC_BLOCK_SIZE); startblk * MMCSD_BLOCK_SIZE);
if (recvr1(mmcp) != 0x00) { if (recvr1(mmcp) != 0x00) {
spiUnselect(mmcp->spip); spiUnselect(mmcp->config->spip);
chSysLock(); chSysLock();
if (mmcp->state == MMC_WRITING) if (mmcp->state == MMC_WRITING)
mmcp->state = MMC_READY; mmcp->state = MMC_READY;
@ -765,17 +761,17 @@ bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) {
} }
chSysUnlock(); chSysUnlock();
spiSend(mmcp->spip, sizeof(start), start); /* Data prologue. */ spiSend(mmcp->config->spip, sizeof(start), start); /* Data prologue. */
spiSend(mmcp->spip, SDMMC_BLOCK_SIZE, buffer); /* Data. */ spiSend(mmcp->config->spip, MMCSD_BLOCK_SIZE, buffer);/* Data. */
spiIgnore(mmcp->spip, 2); /* CRC ignored. */ spiIgnore(mmcp->config->spip, 2); /* CRC ignored. */
spiReceive(mmcp->spip, 1, b); spiReceive(mmcp->config->spip, 1, b);
if ((b[0] & 0x1F) == 0x05) { if ((b[0] & 0x1F) == 0x05) {
wait(mmcp); wait(mmcp);
return FALSE; return FALSE;
} }
/* Error.*/ /* Error.*/
spiUnselect(mmcp->spip); spiUnselect(mmcp->config->spip);
chSysLock(); chSysLock();
if (mmcp->state == MMC_WRITING) if (mmcp->state == MMC_WRITING)
mmcp->state = MMC_READY; mmcp->state = MMC_READY;
@ -806,8 +802,8 @@ bool_t mmcStopSequentialWrite(MMCDriver *mmcp) {
} }
chSysUnlock(); chSysUnlock();
spiSend(mmcp->spip, sizeof(stop), stop); spiSend(mmcp->config->spip, sizeof(stop), stop);
spiUnselect(mmcp->spip); spiUnselect(mmcp->config->spip);
chSysLock(); chSysLock();
if (mmcp->state == MMC_WRITING) { if (mmcp->state == MMC_WRITING) {
@ -871,7 +867,7 @@ bool_t mmcGetInfo(MMCDriver *mmcp, BlockDeviceInfo *bdip) {
chSysUnlock(); chSysUnlock();
bdip->blk_num = 0; /* NOTE: To be implemented.*/ bdip->blk_num = 0; /* NOTE: To be implemented.*/
bdip->blk_size = SDMMC_BLOCK_SIZE; bdip->blk_size = MMCSD_BLOCK_SIZE;
return FALSE; return FALSE;
} }

120
os/hal/src/mmcsd.c Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/**
* @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 */
/** @} */

View File

@ -61,42 +61,6 @@ static const struct MMCSDBlockDeviceVMT sdc_vmt = {
/* Driver local functions. */ /* 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. * @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]; uint32_t resp[1];
while (TRUE) { 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) || sdcp->rca, resp) ||
SDC_R1_ERROR(resp[0])) MMCSD_R1_ERROR(resp[0]))
return CH_FAILED; return CH_FAILED;
switch (SDC_R1_STS(resp[0])) { switch (MMCSD_R1_STS(resp[0])) {
case SDC_STS_TRAN: case MMCSD_STS_TRAN:
return CH_SUCCESS; return CH_SUCCESS;
case SDC_STS_DATA: case MMCSD_STS_DATA:
case SDC_STS_RCV: case MMCSD_STS_RCV:
case SDC_STS_PRG: case MMCSD_STS_PRG:
#if SDC_NICE_WAITING #if SDC_NICE_WAITING
chThdSleepMilliseconds(1); chThdSleepMilliseconds(1);
#endif #endif
@ -239,23 +203,23 @@ bool_t sdcConnect(SDCDriver *sdcp) {
sdc_lld_start_clk(sdcp); sdc_lld_start_clk(sdcp);
/* Enforces the initial card state.*/ /* 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.*/ /* V2.0 cards detection.*/
if (!sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_IF_COND, if (!sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SEND_IF_COND,
SDC_CMD8_PATTERN, resp)) { MMCSD_CMD8_PATTERN, resp)) {
sdcp->cardmode = SDC_MODE_CARDTYPE_SDV20; sdcp->cardmode = SDC_MODE_CARDTYPE_SDV20;
/* Voltage verification.*/ /* Voltage verification.*/
if (((resp[0] >> 8) & 0xF) != 1) if (((resp[0] >> 8) & 0xF) != 1)
goto failed; goto failed;
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) || if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_APP_CMD, 0, resp) ||
SDC_R1_ERROR(resp[0])) MMCSD_R1_ERROR(resp[0]))
goto failed; goto failed;
} }
else { else {
#if SDC_MMC_SUPPORT #if SDC_MMC_SUPPORT
/* MMC or SD V1.1 detection.*/ /* 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])) SDC_R1_ERROR(resp[0]))
sdcp->cardmode = SDC_MODE_CARDTYPE_MMC; sdcp->cardmode = SDC_MODE_CARDTYPE_MMC;
else else
@ -283,10 +247,10 @@ bool_t sdcConnect(SDCDriver *sdcp) {
/* SD-type initialization. */ /* SD-type initialization. */
i = 0; i = 0;
while (TRUE) { while (TRUE) {
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) || if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_APP_CMD, 0, resp) ||
SDC_R1_ERROR(resp[0])) MMCSD_R1_ERROR(resp[0]))
goto failed; 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; goto failed;
if ((resp[0] & 0x80000000) != 0) { if ((resp[0] & 0x80000000) != 0) {
if (resp[0] & 0x40000000) if (resp[0] & 0x40000000)
@ -300,30 +264,31 @@ bool_t sdcConnect(SDCDriver *sdcp) {
} }
/* Reads CID.*/ /* 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; goto failed;
/* Asks for the RCA.*/ /* 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)) 0, &sdcp->rca))
goto failed; goto failed;
/* Reads CSD.*/ /* 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; goto failed;
/* Switches to high speed.*/ /* Switches to high speed.*/
sdc_lld_set_data_clk(sdcp); sdc_lld_set_data_clk(sdcp);
/* Selects the card for operations.*/ /* 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)) sdcp->rca, resp))
goto failed; goto failed;
/* Block length fixed at 512 bytes.*/ /* Block length fixed at 512 bytes.*/
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SET_BLOCKLEN, if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SET_BLOCKLEN,
SDC_BLOCK_SIZE, resp) || MMCSD_BLOCK_SIZE, resp) ||
SDC_R1_ERROR(resp[0])) MMCSD_R1_ERROR(resp[0]))
goto failed; goto failed;
/* Switches to wide bus mode.*/ /* Switches to wide bus mode.*/
@ -331,35 +296,17 @@ bool_t sdcConnect(SDCDriver *sdcp) {
case SDC_MODE_CARDTYPE_SDV11: case SDC_MODE_CARDTYPE_SDV11:
case SDC_MODE_CARDTYPE_SDV20: case SDC_MODE_CARDTYPE_SDV20:
sdc_lld_set_bus_mode(sdcp, SDC_MODE_4BIT); sdc_lld_set_bus_mode(sdcp, SDC_MODE_4BIT);
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, sdcp->rca, resp) || if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_APP_CMD, sdcp->rca, resp) ||
SDC_R1_ERROR(resp[0])) MMCSD_R1_ERROR(resp[0]))
goto failed; goto failed;
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SET_BUS_WIDTH, 2, resp) || if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SET_BUS_WIDTH, 2, resp) ||
SDC_R1_ERROR(resp[0])) MMCSD_R1_ERROR(resp[0]))
goto failed; goto failed;
break; break;
} }
/* Determine capacity.*/ /* Determine capacity.*/
switch (sdcp->csd[3] >> 30) { sdcp->capacity = mmcsdGetCapacity(sdcp->csd);
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;
}
if (sdcp->capacity == 0) if (sdcp->capacity == 0)
goto failed; goto failed;
@ -553,7 +500,7 @@ bool_t sdcGetInfo(SDCDriver *sdcp, BlockDeviceInfo *bdip) {
chSysUnlock(); chSysUnlock();
bdip->blk_num = 0; /* NOTE: To be implemented.*/ bdip->blk_num = 0; /* NOTE: To be implemented.*/
bdip->blk_size = SDMMC_BLOCK_SIZE; bdip->blk_size = MMCSD_BLOCK_SIZE;
return FALSE; return FALSE;
} }

View File

@ -219,7 +219,7 @@ DRESULT disk_ioctl (
*((DWORD *)buff) = sdcGetCardCapacity(&SDCD1); *((DWORD *)buff) = sdcGetCardCapacity(&SDCD1);
return RES_OK; return RES_OK;
case GET_SECTOR_SIZE: case GET_SECTOR_SIZE:
*((WORD *)buff) = SDC_BLOCK_SIZE; *((WORD *)buff) = MMCSD_BLOCK_SIZE;
return RES_OK; return RES_OK;
case GET_BLOCK_SIZE: case GET_BLOCK_SIZE:
*((DWORD *)buff) = 256; /* 512b blocks in one erase block */ *((DWORD *)buff) = 256; /* 512b blocks in one erase block */

View File

@ -123,11 +123,14 @@
3484947)(backported to 2.4.1). 3484947)(backported to 2.4.1).
- FIX: Fixed various minor documentation errors (bug 3484942)(backported - FIX: Fixed various minor documentation errors (bug 3484942)(backported
to 2.4.1). 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 - NEW: Modified the SDC driver to implement the new block devices abstract
interface. interface.
- NEW: Added two new functions to the MMC_SPI driver: mmcSync() and - NEW: Added two new functions to the MMC_SPI driver: mmcSync() and
mmc_Get_Info(). Also implemented the new block devices abstract 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 - 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 abstraction layer is meant to unify the access protocol to the SDC and
MMC_SPI (and potentially others) device drivers. MMC_SPI (and potentially others) device drivers.