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();
}
#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.
*/

View File

@ -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.
*/

View File

@ -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.
*/

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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);
}

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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. */
/*===========================================================================*/

View File

@ -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++;

View File

@ -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. */
/*===========================================================================*/

View File

@ -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;
}

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. */
/*===========================================================================*/
/**
* @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;
}

View File

@ -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 */

View File

@ -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.