git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4180 35acf78f-673a-0410-8e92-d51de3d6d3f4
parent
6a8a643ab0
commit
97dce7b944
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,41 +46,6 @@
|
|||
#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
|
||||
* @{
|
||||
|
@ -95,11 +53,11 @@
|
|||
#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_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 not detected.*/
|
||||
#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. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/** @} */
|
113
os/hal/src/sdc.c
113
os/hal/src/sdc.c
|
@ -61,42 +61,6 @@ static const struct MMCSDBlockDeviceVMT sdc_vmt = {
|
|||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Get slice with data from uint32_t[4] array.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static uint32_t _sdc_get_slice(uint32_t *data, int32_t end, int32_t start) {
|
||||
uint32_t word = 0;
|
||||
uint32_t mask = 0;
|
||||
|
||||
chDbgCheck(((start >=0) && (end >=0) && (end >= start)), "sdc_get_slice");
|
||||
|
||||
while ((start - 32 * word) > 31){
|
||||
word++;
|
||||
data++;
|
||||
}
|
||||
|
||||
end -= 32 * word;
|
||||
start -= 32 * word;
|
||||
|
||||
if (end < 31){
|
||||
/* Value lays in one word.*/
|
||||
mask = (1 << (end - start + 1)) - 1;
|
||||
return (*data >> start) & mask;
|
||||
}
|
||||
else{
|
||||
/* Value spread on separate words.*/
|
||||
uint32_t lsb, msb;
|
||||
lsb = *data >> start;
|
||||
data++;
|
||||
mask = (1 << (end - 32 + 1)) - 1;
|
||||
msb = *data & mask;
|
||||
msb = msb << (32 - start);
|
||||
return (msb | lsb);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait for the card to complete pending operations.
|
||||
*
|
||||
|
@ -112,16 +76,16 @@ bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp) {
|
|||
uint32_t resp[1];
|
||||
|
||||
while (TRUE) {
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_STATUS,
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SEND_STATUS,
|
||||
sdcp->rca, resp) ||
|
||||
SDC_R1_ERROR(resp[0]))
|
||||
MMCSD_R1_ERROR(resp[0]))
|
||||
return CH_FAILED;
|
||||
switch (SDC_R1_STS(resp[0])) {
|
||||
case SDC_STS_TRAN:
|
||||
switch (MMCSD_R1_STS(resp[0])) {
|
||||
case MMCSD_STS_TRAN:
|
||||
return CH_SUCCESS;
|
||||
case SDC_STS_DATA:
|
||||
case SDC_STS_RCV:
|
||||
case SDC_STS_PRG:
|
||||
case MMCSD_STS_DATA:
|
||||
case MMCSD_STS_RCV:
|
||||
case MMCSD_STS_PRG:
|
||||
#if SDC_NICE_WAITING
|
||||
chThdSleepMilliseconds(1);
|
||||
#endif
|
||||
|
@ -239,23 +203,23 @@ bool_t sdcConnect(SDCDriver *sdcp) {
|
|||
sdc_lld_start_clk(sdcp);
|
||||
|
||||
/* Enforces the initial card state.*/
|
||||
sdc_lld_send_cmd_none(sdcp, SDC_CMD_GO_IDLE_STATE, 0);
|
||||
sdc_lld_send_cmd_none(sdcp, MMCSD_CMD_GO_IDLE_STATE, 0);
|
||||
|
||||
/* V2.0 cards detection.*/
|
||||
if (!sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_IF_COND,
|
||||
SDC_CMD8_PATTERN, resp)) {
|
||||
if (!sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SEND_IF_COND,
|
||||
MMCSD_CMD8_PATTERN, resp)) {
|
||||
sdcp->cardmode = SDC_MODE_CARDTYPE_SDV20;
|
||||
/* Voltage verification.*/
|
||||
if (((resp[0] >> 8) & 0xF) != 1)
|
||||
goto failed;
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) ||
|
||||
SDC_R1_ERROR(resp[0]))
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_APP_CMD, 0, resp) ||
|
||||
MMCSD_R1_ERROR(resp[0]))
|
||||
goto failed;
|
||||
}
|
||||
else {
|
||||
#if SDC_MMC_SUPPORT
|
||||
/* MMC or SD V1.1 detection.*/
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) ||
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, SDMMC_CMD_APP_CMD, 0, resp) ||
|
||||
SDC_R1_ERROR(resp[0]))
|
||||
sdcp->cardmode = SDC_MODE_CARDTYPE_MMC;
|
||||
else
|
||||
|
@ -283,10 +247,10 @@ bool_t sdcConnect(SDCDriver *sdcp) {
|
|||
/* SD-type initialization. */
|
||||
i = 0;
|
||||
while (TRUE) {
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, 0, resp) ||
|
||||
SDC_R1_ERROR(resp[0]))
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_APP_CMD, 0, resp) ||
|
||||
MMCSD_R1_ERROR(resp[0]))
|
||||
goto failed;
|
||||
if (sdc_lld_send_cmd_short(sdcp, SDC_CMD_APP_OP_COND, ocr, resp))
|
||||
if (sdc_lld_send_cmd_short(sdcp, MMCSD_CMD_APP_OP_COND, ocr, resp))
|
||||
goto failed;
|
||||
if ((resp[0] & 0x80000000) != 0) {
|
||||
if (resp[0] & 0x40000000)
|
||||
|
@ -300,30 +264,31 @@ bool_t sdcConnect(SDCDriver *sdcp) {
|
|||
}
|
||||
|
||||
/* Reads CID.*/
|
||||
if (sdc_lld_send_cmd_long_crc(sdcp, SDC_CMD_ALL_SEND_CID, 0, sdcp->cid))
|
||||
if (sdc_lld_send_cmd_long_crc(sdcp, MMCSD_CMD_ALL_SEND_CID, 0, sdcp->cid))
|
||||
goto failed;
|
||||
|
||||
/* Asks for the RCA.*/
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_RELATIVE_ADDR,
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SEND_RELATIVE_ADDR,
|
||||
0, &sdcp->rca))
|
||||
goto failed;
|
||||
|
||||
/* Reads CSD.*/
|
||||
if (sdc_lld_send_cmd_long_crc(sdcp, SDC_CMD_SEND_CSD, sdcp->rca, sdcp->csd))
|
||||
if (sdc_lld_send_cmd_long_crc(sdcp, MMCSD_CMD_SEND_CSD,
|
||||
sdcp->rca, sdcp->csd))
|
||||
goto failed;
|
||||
|
||||
/* Switches to high speed.*/
|
||||
sdc_lld_set_data_clk(sdcp);
|
||||
|
||||
/* Selects the card for operations.*/
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEL_DESEL_CARD,
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SEL_DESEL_CARD,
|
||||
sdcp->rca, resp))
|
||||
goto failed;
|
||||
|
||||
/* Block length fixed at 512 bytes.*/
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SET_BLOCKLEN,
|
||||
SDC_BLOCK_SIZE, resp) ||
|
||||
SDC_R1_ERROR(resp[0]))
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SET_BLOCKLEN,
|
||||
MMCSD_BLOCK_SIZE, resp) ||
|
||||
MMCSD_R1_ERROR(resp[0]))
|
||||
goto failed;
|
||||
|
||||
/* Switches to wide bus mode.*/
|
||||
|
@ -331,35 +296,17 @@ bool_t sdcConnect(SDCDriver *sdcp) {
|
|||
case SDC_MODE_CARDTYPE_SDV11:
|
||||
case SDC_MODE_CARDTYPE_SDV20:
|
||||
sdc_lld_set_bus_mode(sdcp, SDC_MODE_4BIT);
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_APP_CMD, sdcp->rca, resp) ||
|
||||
SDC_R1_ERROR(resp[0]))
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_APP_CMD, sdcp->rca, resp) ||
|
||||
MMCSD_R1_ERROR(resp[0]))
|
||||
goto failed;
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SET_BUS_WIDTH, 2, resp) ||
|
||||
SDC_R1_ERROR(resp[0]))
|
||||
if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SET_BUS_WIDTH, 2, resp) ||
|
||||
MMCSD_R1_ERROR(resp[0]))
|
||||
goto failed;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Determine capacity.*/
|
||||
switch (sdcp->csd[3] >> 30) {
|
||||
uint32_t a, b, c;
|
||||
case 0:
|
||||
/* CSD version 1.0 */
|
||||
a = _sdc_get_slice(sdcp->csd, SDC_CSD_10_C_SIZE_SLICE);
|
||||
b = _sdc_get_slice(sdcp->csd, SDC_CSD_10_C_SIZE_MULT_SLICE);
|
||||
c = _sdc_get_slice(sdcp->csd, SDC_CSD_10_READ_BL_LEN_SLICE);
|
||||
sdcp->capacity = ((a + 1) << (b + 2) << c) / 512;
|
||||
break;
|
||||
case 1:
|
||||
/* CSD version 2.0 */
|
||||
a = _sdc_get_slice(sdcp->csd, SDC_CSD_20_C_SIZE_SLICE);
|
||||
sdcp->capacity = 1024 * (a + 1);
|
||||
break;
|
||||
default:
|
||||
/* Reserved value detected. */
|
||||
sdcp->capacity = 0;
|
||||
break;
|
||||
}
|
||||
sdcp->capacity = mmcsdGetCapacity(sdcp->csd);
|
||||
if (sdcp->capacity == 0)
|
||||
goto failed;
|
||||
|
||||
|
@ -553,7 +500,7 @@ bool_t sdcGetInfo(SDCDriver *sdcp, BlockDeviceInfo *bdip) {
|
|||
chSysUnlock();
|
||||
|
||||
bdip->blk_num = 0; /* NOTE: To be implemented.*/
|
||||
bdip->blk_size = SDMMC_BLOCK_SIZE;
|
||||
bdip->blk_size = MMCSD_BLOCK_SIZE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue