From e42ca31b0f62818ed84c144eea7195515da7924f Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Mon, 23 Feb 2015 14:23:15 +0000 Subject: limit the use of scratchpad buffer git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7697 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/hal_mmcsd.h | 24 ++-- os/hal/ports/STM32/LLD/sdc_lld.h | 21 +-- os/hal/src/hal_mmcsd.c | 287 +++++++++++++++++++-------------------- os/hal/src/mmc_spi.c | 2 +- os/hal/src/sdc.c | 56 +++++--- os/hal/templates/sdc_lld.h | 9 +- 6 files changed, 213 insertions(+), 186 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/hal_mmcsd.h b/os/hal/include/hal_mmcsd.h index 18af3bd69..44094189d 100644 --- a/os/hal/include/hal_mmcsd.h +++ b/os/hal/include/hal_mmcsd.h @@ -475,15 +475,21 @@ typedef struct { #ifdef __cplusplus extern "C" { #endif - uint32_t mmcsdGetSlice(const uint32_t *data, uint32_t end, uint32_t start); - uint32_t mmcsdGetCapacity(const uint32_t *csd); - uint32_t mmcsdGetCapacityMMC(const uint32_t *csd, const uint8_t *ext_csd); - void sdcUnpackCID(const MMCSDBlockDevice *sdcp, unpacked_sdc_cid_t *cidsdc); - void mmcUnpackCID(const MMCSDBlockDevice *sdcp, unpacked_mmc_cid_t *cidmmc); - void sdcUnpackCSDv10(const MMCSDBlockDevice *sdcp, - unpacked_sdc_csd_10_t *csd10); - void sdcUnpackCSDv20(const MMCSDBlockDevice *sdcp, - unmacked_sdc_csd_20_t *csd20); + uint32_t _mmcsd_get_slice(const uint32_t *data, + uint32_t end, + uint32_t start); + uint32_t _mmcsd_get_capacity(const uint32_t *csd); + uint32_t _mmcsd_get_capacity_ext(const uint8_t *ext_csd); + void _mmcsd_unpack_sdc_cid(const MMCSDBlockDevice *sdcp, + unpacked_sdc_cid_t *cidsdc); + void _mmcsd_unpack_mmc_cid(const MMCSDBlockDevice *sdcp, + unpacked_mmc_cid_t *cidmmc); + void _mmcsd_unpack_csd_mmc(const MMCSDBlockDevice *sdcp, + unpacked_mmc_csd_t *csdmmc); + void _mmcsd_unpack_csd_v10(const MMCSDBlockDevice *sdcp, + unpacked_sdc_csd_10_t *csd10); + void _mmcsd_unpack_csd_v20(const MMCSDBlockDevice *sdcp, + unmacked_sdc_csd_20_t *csd20); #ifdef __cplusplus } #endif diff --git a/os/hal/ports/STM32/LLD/sdc_lld.h b/os/hal/ports/STM32/LLD/sdc_lld.h index 8c0f7eb4c..dbad8df76 100644 --- a/os/hal/ports/STM32/LLD/sdc_lld.h +++ b/os/hal/ports/STM32/LLD/sdc_lld.h @@ -219,18 +219,19 @@ typedef struct SDCDriver SDCDriver; */ typedef struct { /** - * @brief Bus width (board specific). - */ - sdcbusmode_t bus_width; - /** - * @brief Working area for memory consuming operations during init - * procedures (temporal storage for EXT_CSD, etc.). + * @brief Working area for memory consuming operations. * @note Buffer must be word aligned and big enough to store 512 bytes. - * @note It is mandatory for MMC bigger than 2GB. - * @note Memory can be freed after @p sdcConnect return. Do not - * forget to set this pointer to @p NULL after freeing. + * @note It is mandatory for detecting MMC cards bigger than 2GB else it + * can be @p NULL. + * @note Memory pointed by this buffer is only used by @p sdcConnect(), + * afterward it can be reused for other purposes. */ uint8_t *scratchpad; + /* End of the mandatory fields.*/ + /** + * @brief Bus width. + */ + sdcbusmode_t bus_width; } SDCConfig; /** @@ -288,7 +289,7 @@ struct SDCDriver { const stm32_dma_stream_t *dma; /** * @brief Pointer to the SDIO registers block. - * @note Needed for dubugging aid. + * @note Needed for debugging aid. */ SDIO_TypeDef *sdio; }; diff --git a/os/hal/src/hal_mmcsd.c b/os/hal/src/hal_mmcsd.c index d113c5ebd..4d89e53e4 100644 --- a/os/hal/src/hal_mmcsd.c +++ b/os/hal/src/hal_mmcsd.c @@ -61,7 +61,9 @@ * * @notapi */ -uint32_t mmcsdGetSlice(const uint32_t *data, uint32_t end, uint32_t start) { +uint32_t _mmcsd_get_slice(const uint32_t *data, + uint32_t end, + uint32_t start) { unsigned startidx, endidx, startoff; uint32_t endmask; @@ -87,22 +89,24 @@ uint32_t mmcsdGetSlice(const uint32_t *data, uint32_t end, uint32_t start) { * * @return The card capacity. * @retval 0 CSD format error + * + * @notapi */ -uint32_t mmcsdGetCapacity(const uint32_t *csd) { +uint32_t _mmcsd_get_capacity(const uint32_t *csd) { uint32_t a, b, c; osalDbgCheck(NULL != csd); - switch (mmcsdGetSlice(csd, MMCSD_CSD_10_CSD_STRUCTURE_SLICE)) { + switch (_mmcsd_get_slice(csd, MMCSD_CSD_10_CSD_STRUCTURE_SLICE)) { case 0: /* CSD version 1.0 */ - a = mmcsdGetSlice(csd, MMCSD_CSD_10_C_SIZE_SLICE); - b = mmcsdGetSlice(csd, MMCSD_CSD_10_C_SIZE_MULT_SLICE); - c = mmcsdGetSlice(csd, MMCSD_CSD_10_READ_BL_LEN_SLICE); + 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 * (mmcsdGetSlice(csd, MMCSD_CSD_20_C_SIZE_SLICE) + 1); + return 1024 * (_mmcsd_get_slice(csd, MMCSD_CSD_20_C_SIZE_SLICE) + 1); default: /* Reserved value detected.*/ return 0; @@ -110,33 +114,23 @@ uint32_t mmcsdGetCapacity(const uint32_t *csd) { } /** - * @brief Extract MMC card capacity from a CSD or EXT_CSD. + * @brief Extract MMC card capacity from EXT_CSD. * @details The capacity is returned as number of available blocks. * - * @param[in] csd the CSD record * @param[in] ext_csd the extended CSD record * * @return The card capacity. + * + * @notapi */ -uint32_t mmcsdGetCapacityMMC(const uint32_t *csd, const uint8_t *ext_csd) { - uint32_t a, b, c; +uint32_t _mmcsd_get_capacity_ext(const uint8_t *ext_csd) { - osalDbgCheck(NULL != csd); + osalDbgCheck(NULL != ext_csd); - a = mmcsdGetSlice(csd, MMCSD_CSD_MMC_C_SIZE_SLICE); - if (0xFFF != a) { - b = mmcsdGetSlice(csd, MMCSD_CSD_MMC_C_SIZE_MULT_SLICE); - c = mmcsdGetSlice(csd, MMCSD_CSD_MMC_READ_BL_LEN_SLICE); - return (a + 1) << (b + 2) << (c - 9); /* 2^9 == MMCSD_BLOCK_SIZE. */ - } - else if (NULL != ext_csd) { - return (ext_csd[215] << 24) + - (ext_csd[214] << 16) + - (ext_csd[213] << 8) + - ext_csd[212]; - } - else - return 0; + return (ext_csd[215] << 24) + + (ext_csd[214] << 16) + + (ext_csd[213] << 8) + + ext_csd[212]; } /** @@ -147,25 +141,26 @@ uint32_t mmcsdGetCapacityMMC(const uint32_t *csd, const uint8_t *ext_csd) { * * @api */ -void sdcUnpackCID(const MMCSDBlockDevice *sdcp, unpacked_sdc_cid_t *cidsdc) { +void _mmcsd_unpack_sdc_cid(const MMCSDBlockDevice *sdcp, + unpacked_sdc_cid_t *cidsdc) { const uint32_t *cid; osalDbgCheck((NULL != sdcp) && (NULL != cidsdc)); - cid = sdcp->cid; - cidsdc->crc = mmcsdGetSlice(cid, MMCSD_CID_SDC_CRC_SLICE); - cidsdc->mdt_y = mmcsdGetSlice(cid, MMCSD_CID_SDC_MDT_Y_SLICE) + 2000; - cidsdc->mdt_m = mmcsdGetSlice(cid, MMCSD_CID_SDC_MDT_M_SLICE); - cidsdc->mid = mmcsdGetSlice(cid, MMCSD_CID_SDC_MID_SLICE); - cidsdc->oid = mmcsdGetSlice(cid, MMCSD_CID_SDC_OID_SLICE); - cidsdc->pnm[4] = mmcsdGetSlice(cid, MMCSD_CID_SDC_PNM0_SLICE); - cidsdc->pnm[3] = mmcsdGetSlice(cid, MMCSD_CID_SDC_PNM1_SLICE); - cidsdc->pnm[2] = mmcsdGetSlice(cid, MMCSD_CID_SDC_PNM2_SLICE); - cidsdc->pnm[1] = mmcsdGetSlice(cid, MMCSD_CID_SDC_PNM3_SLICE); - cidsdc->pnm[0] = mmcsdGetSlice(cid, MMCSD_CID_SDC_PNM4_SLICE); - cidsdc->prv_n = mmcsdGetSlice(cid, MMCSD_CID_SDC_PRV_N_SLICE); - cidsdc->prv_m = mmcsdGetSlice(cid, MMCSD_CID_SDC_PRV_M_SLICE); - cidsdc->psn = mmcsdGetSlice(cid, MMCSD_CID_SDC_PSN_SLICE); + cid = sdcp->cid; + cidsdc->crc = _mmcsd_get_slice(cid, MMCSD_CID_SDC_CRC_SLICE); + cidsdc->mdt_y = _mmcsd_get_slice(cid, MMCSD_CID_SDC_MDT_Y_SLICE) + 2000; + cidsdc->mdt_m = _mmcsd_get_slice(cid, MMCSD_CID_SDC_MDT_M_SLICE); + cidsdc->mid = _mmcsd_get_slice(cid, MMCSD_CID_SDC_MID_SLICE); + cidsdc->oid = _mmcsd_get_slice(cid, MMCSD_CID_SDC_OID_SLICE); + cidsdc->pnm[4] = _mmcsd_get_slice(cid, MMCSD_CID_SDC_PNM0_SLICE); + cidsdc->pnm[3] = _mmcsd_get_slice(cid, MMCSD_CID_SDC_PNM1_SLICE); + cidsdc->pnm[2] = _mmcsd_get_slice(cid, MMCSD_CID_SDC_PNM2_SLICE); + cidsdc->pnm[1] = _mmcsd_get_slice(cid, MMCSD_CID_SDC_PNM3_SLICE); + cidsdc->pnm[0] = _mmcsd_get_slice(cid, MMCSD_CID_SDC_PNM4_SLICE); + cidsdc->prv_n = _mmcsd_get_slice(cid, MMCSD_CID_SDC_PRV_N_SLICE); + cidsdc->prv_m = _mmcsd_get_slice(cid, MMCSD_CID_SDC_PRV_M_SLICE); + cidsdc->psn = _mmcsd_get_slice(cid, MMCSD_CID_SDC_PSN_SLICE); } /** @@ -176,26 +171,27 @@ void sdcUnpackCID(const MMCSDBlockDevice *sdcp, unpacked_sdc_cid_t *cidsdc) { * * @api */ -void mmcUnpackCID(const MMCSDBlockDevice *sdcp, unpacked_mmc_cid_t *cidmmc) { +void _mmcsd_unpack_mmc_cid(const MMCSDBlockDevice *sdcp, + unpacked_mmc_cid_t *cidmmc) { const uint32_t *cid; osalDbgCheck((NULL != sdcp) && (NULL != cidmmc)); - cid = sdcp->cid; - cidmmc->crc = mmcsdGetSlice(cid, MMCSD_CID_MMC_CRC_SLICE); - cidmmc->mdt_y = mmcsdGetSlice(cid, MMCSD_CID_MMC_MDT_Y_SLICE) + 1997; - cidmmc->mdt_m = mmcsdGetSlice(cid, MMCSD_CID_MMC_MDT_M_SLICE); - cidmmc->mid = mmcsdGetSlice(cid, MMCSD_CID_MMC_MID_SLICE); - cidmmc->oid = mmcsdGetSlice(cid, MMCSD_CID_MMC_OID_SLICE); - cidmmc->pnm[5] = mmcsdGetSlice(cid, MMCSD_CID_MMC_PNM0_SLICE); - cidmmc->pnm[4] = mmcsdGetSlice(cid, MMCSD_CID_MMC_PNM1_SLICE); - cidmmc->pnm[3] = mmcsdGetSlice(cid, MMCSD_CID_MMC_PNM2_SLICE); - cidmmc->pnm[2] = mmcsdGetSlice(cid, MMCSD_CID_MMC_PNM3_SLICE); - cidmmc->pnm[1] = mmcsdGetSlice(cid, MMCSD_CID_MMC_PNM4_SLICE); - cidmmc->pnm[0] = mmcsdGetSlice(cid, MMCSD_CID_MMC_PNM5_SLICE); - cidmmc->prv_n = mmcsdGetSlice(cid, MMCSD_CID_MMC_PRV_N_SLICE); - cidmmc->prv_m = mmcsdGetSlice(cid, MMCSD_CID_MMC_PRV_M_SLICE); - cidmmc->psn = mmcsdGetSlice(cid, MMCSD_CID_MMC_PSN_SLICE); + cid = sdcp->cid; + cidmmc->crc = _mmcsd_get_slice(cid, MMCSD_CID_MMC_CRC_SLICE); + cidmmc->mdt_y = _mmcsd_get_slice(cid, MMCSD_CID_MMC_MDT_Y_SLICE) + 1997; + cidmmc->mdt_m = _mmcsd_get_slice(cid, MMCSD_CID_MMC_MDT_M_SLICE); + cidmmc->mid = _mmcsd_get_slice(cid, MMCSD_CID_MMC_MID_SLICE); + cidmmc->oid = _mmcsd_get_slice(cid, MMCSD_CID_MMC_OID_SLICE); + cidmmc->pnm[5] = _mmcsd_get_slice(cid, MMCSD_CID_MMC_PNM0_SLICE); + cidmmc->pnm[4] = _mmcsd_get_slice(cid, MMCSD_CID_MMC_PNM1_SLICE); + cidmmc->pnm[3] = _mmcsd_get_slice(cid, MMCSD_CID_MMC_PNM2_SLICE); + cidmmc->pnm[2] = _mmcsd_get_slice(cid, MMCSD_CID_MMC_PNM3_SLICE); + cidmmc->pnm[1] = _mmcsd_get_slice(cid, MMCSD_CID_MMC_PNM4_SLICE); + cidmmc->pnm[0] = _mmcsd_get_slice(cid, MMCSD_CID_MMC_PNM5_SLICE); + cidmmc->prv_n = _mmcsd_get_slice(cid, MMCSD_CID_MMC_PRV_N_SLICE); + cidmmc->prv_m = _mmcsd_get_slice(cid, MMCSD_CID_MMC_PRV_M_SLICE); + cidmmc->psn = _mmcsd_get_slice(cid, MMCSD_CID_MMC_PSN_SLICE); } /** @@ -206,43 +202,44 @@ void mmcUnpackCID(const MMCSDBlockDevice *sdcp, unpacked_mmc_cid_t *cidmmc) { * * @api */ -void mmcUnpackCSD(const MMCSDBlockDevice *sdcp, unpacked_mmc_csd_t *csdmmc) { +void _mmcsd_unpack_csd_mmc(const MMCSDBlockDevice *sdcp, + unpacked_mmc_csd_t *csdmmc) { const uint32_t *csd; osalDbgCheck((NULL != sdcp) && (NULL != csdmmc)); - csd = sdcp->csd; - csdmmc->c_size = mmcsdGetSlice(csd, MMCSD_CSD_MMC_C_SIZE_SLICE); - csdmmc->c_size_mult = mmcsdGetSlice(csd, MMCSD_CSD_MMC_C_SIZE_MULT_SLICE); - csdmmc->ccc = mmcsdGetSlice(csd, MMCSD_CSD_MMC_CCC_SLICE); - csdmmc->copy = mmcsdGetSlice(csd, MMCSD_CSD_MMC_COPY_SLICE); - csdmmc->crc = mmcsdGetSlice(csd, MMCSD_CSD_MMC_CRC_SLICE); - csdmmc->csd_structure = mmcsdGetSlice(csd, MMCSD_CSD_MMC_CSD_STRUCTURE_SLICE); - csdmmc->dsr_imp = mmcsdGetSlice(csd, MMCSD_CSD_MMC_DSR_IMP_SLICE); - csdmmc->ecc = mmcsdGetSlice(csd, MMCSD_CSD_MMC_ECC_SLICE); - csdmmc->erase_grp_mult = mmcsdGetSlice(csd, MMCSD_CSD_MMC_ERASE_GRP_MULT_SLICE); - csdmmc->erase_grp_size = mmcsdGetSlice(csd, MMCSD_CSD_MMC_ERASE_GRP_SIZE_SLICE); - csdmmc->file_format = mmcsdGetSlice(csd, MMCSD_CSD_MMC_FILE_FORMAT_SLICE); - csdmmc->file_format_grp = mmcsdGetSlice(csd, MMCSD_CSD_MMC_FILE_FORMAT_GRP_SLICE); - csdmmc->nsac = mmcsdGetSlice(csd, MMCSD_CSD_MMC_NSAC_SLICE); - csdmmc->perm_write_protect = mmcsdGetSlice(csd, MMCSD_CSD_MMC_PERM_WRITE_PROTECT_SLICE); - csdmmc->r2w_factor = mmcsdGetSlice(csd, MMCSD_CSD_MMC_R2W_FACTOR_SLICE); - csdmmc->read_bl_len = mmcsdGetSlice(csd, MMCSD_CSD_MMC_READ_BL_LEN_SLICE); - csdmmc->read_bl_partial = mmcsdGetSlice(csd, MMCSD_CSD_MMC_READ_BL_PARTIAL_SLICE); - csdmmc->read_blk_misalign = mmcsdGetSlice(csd, MMCSD_CSD_MMC_READ_BLK_MISALIGN_SLICE); - csdmmc->spec_vers = mmcsdGetSlice(csd, MMCSD_CSD_MMC_SPEC_VERS_SLICE); - csdmmc->taac = mmcsdGetSlice(csd, MMCSD_CSD_MMC_TAAC_SLICE); - csdmmc->tmp_write_protect = mmcsdGetSlice(csd, MMCSD_CSD_MMC_TMP_WRITE_PROTECT_SLICE); - csdmmc->tran_speed = mmcsdGetSlice(csd, MMCSD_CSD_MMC_TRAN_SPEED_SLICE); - csdmmc->vdd_r_curr_max = mmcsdGetSlice(csd, MMCSD_CSD_MMC_VDD_R_CURR_MAX_SLICE); - csdmmc->vdd_r_curr_min = mmcsdGetSlice(csd, MMCSD_CSD_MMC_VDD_R_CURR_MIN_SLICE); - csdmmc->vdd_w_curr_max = mmcsdGetSlice(csd, MMCSD_CSD_MMC_VDD_W_CURR_MAX_SLICE); - csdmmc->vdd_w_curr_min = mmcsdGetSlice(csd, MMCSD_CSD_MMC_VDD_W_CURR_MIN_SLICE); - csdmmc->wp_grp_enable = mmcsdGetSlice(csd, MMCSD_CSD_MMC_WP_GRP_ENABLE_SLICE); - csdmmc->wp_grp_size = mmcsdGetSlice(csd, MMCSD_CSD_MMC_WP_GRP_SIZE_SLICE); - csdmmc->write_bl_len = mmcsdGetSlice(csd, MMCSD_CSD_MMC_WRITE_BL_LEN_SLICE); - csdmmc->write_bl_partial = mmcsdGetSlice(csd, MMCSD_CSD_MMC_WRITE_BL_PARTIAL_SLICE); - csdmmc->write_blk_misalign = mmcsdGetSlice(csd, MMCSD_CSD_MMC_WRITE_BLK_MISALIGN_SLICE); + csd = sdcp->csd; + csdmmc->c_size = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_C_SIZE_SLICE); + csdmmc->c_size_mult = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_C_SIZE_MULT_SLICE); + csdmmc->ccc = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_CCC_SLICE); + csdmmc->copy = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_COPY_SLICE); + csdmmc->crc = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_CRC_SLICE); + csdmmc->csd_structure = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_CSD_STRUCTURE_SLICE); + csdmmc->dsr_imp = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_DSR_IMP_SLICE); + csdmmc->ecc = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_ECC_SLICE); + csdmmc->erase_grp_mult = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_ERASE_GRP_MULT_SLICE); + csdmmc->erase_grp_size = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_ERASE_GRP_SIZE_SLICE); + csdmmc->file_format = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_FILE_FORMAT_SLICE); + csdmmc->file_format_grp = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_FILE_FORMAT_GRP_SLICE); + csdmmc->nsac = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_NSAC_SLICE); + csdmmc->perm_write_protect = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_PERM_WRITE_PROTECT_SLICE); + csdmmc->r2w_factor = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_R2W_FACTOR_SLICE); + csdmmc->read_bl_len = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_READ_BL_LEN_SLICE); + csdmmc->read_bl_partial = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_READ_BL_PARTIAL_SLICE); + csdmmc->read_blk_misalign = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_READ_BLK_MISALIGN_SLICE); + csdmmc->spec_vers = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_SPEC_VERS_SLICE); + csdmmc->taac = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_TAAC_SLICE); + csdmmc->tmp_write_protect = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_TMP_WRITE_PROTECT_SLICE); + csdmmc->tran_speed = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_TRAN_SPEED_SLICE); + csdmmc->vdd_r_curr_max = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_VDD_R_CURR_MAX_SLICE); + csdmmc->vdd_r_curr_min = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_VDD_R_CURR_MIN_SLICE); + csdmmc->vdd_w_curr_max = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_VDD_W_CURR_MAX_SLICE); + csdmmc->vdd_w_curr_min = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_VDD_W_CURR_MIN_SLICE); + csdmmc->wp_grp_enable = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_WP_GRP_ENABLE_SLICE); + csdmmc->wp_grp_size = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_WP_GRP_SIZE_SLICE); + csdmmc->write_bl_len = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_WRITE_BL_LEN_SLICE); + csdmmc->write_bl_partial = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_WRITE_BL_PARTIAL_SLICE); + csdmmc->write_blk_misalign = _mmcsd_get_slice(csd, MMCSD_CSD_MMC_WRITE_BLK_MISALIGN_SLICE); } /** @@ -253,38 +250,38 @@ void mmcUnpackCSD(const MMCSDBlockDevice *sdcp, unpacked_mmc_csd_t *csdmmc) { * * @api */ -void sdcUnpackCSDv10(const MMCSDBlockDevice *sdcp, - unpacked_sdc_csd_10_t *csd10) { +void _mmcsd_unpack_csd_v10(const MMCSDBlockDevice *sdcp, + unpacked_sdc_csd_10_t *csd10) { const uint32_t *csd; osalDbgCheck(NULL != sdcp); - csd = sdcp->csd; - csd10->c_size = mmcsdGetSlice(csd, MMCSD_CSD_10_C_SIZE_SLICE); - csd10->c_size_mult = mmcsdGetSlice(csd, MMCSD_CSD_10_C_SIZE_MULT_SLICE); - csd10->ccc = mmcsdGetSlice(csd, MMCSD_CSD_10_CCC_SLICE); - csd10->copy = mmcsdGetSlice(csd, MMCSD_CSD_10_COPY_SLICE); - csd10->crc = mmcsdGetSlice(csd, MMCSD_CSD_10_CRC_SLICE); - csd10->csd_structure = mmcsdGetSlice(csd, MMCSD_CSD_10_CSD_STRUCTURE_SLICE); - csd10->dsr_imp = mmcsdGetSlice(csd, MMCSD_CSD_10_DSR_IMP_SLICE); - csd10->erase_blk_en = mmcsdGetSlice(csd, MMCSD_CSD_10_ERASE_BLK_EN_SLICE); - csd10->erase_sector_size = mmcsdGetSlice(csd, MMCSD_CSD_10_ERASE_SECTOR_SIZE_SLICE); - csd10->file_format = mmcsdGetSlice(csd, MMCSD_CSD_10_FILE_FORMAT_SLICE); - csd10->file_format_grp = mmcsdGetSlice(csd, MMCSD_CSD_10_FILE_FORMAT_GRP_SLICE); - csd10->nsac = mmcsdGetSlice(csd, MMCSD_CSD_10_NSAC_SLICE); - csd10->perm_write_protect = mmcsdGetSlice(csd, MMCSD_CSD_10_PERM_WRITE_PROTECT_SLICE); - csd10->r2w_factor = mmcsdGetSlice(csd, MMCSD_CSD_10_R2W_FACTOR_SLICE); - csd10->read_bl_len = mmcsdGetSlice(csd, MMCSD_CSD_10_READ_BL_LEN_SLICE); - csd10->read_bl_partial = mmcsdGetSlice(csd, MMCSD_CSD_10_READ_BL_PARTIAL_SLICE); - csd10->read_blk_misalign = mmcsdGetSlice(csd, MMCSD_CSD_10_READ_BLK_MISALIGN_SLICE); - csd10->taac = mmcsdGetSlice(csd, MMCSD_CSD_10_TAAC_SLICE); - csd10->tmp_write_protect = mmcsdGetSlice(csd, MMCSD_CSD_10_TMP_WRITE_PROTECT_SLICE); - csd10->tran_speed = mmcsdGetSlice(csd, MMCSD_CSD_10_TRANS_SPEED_SLICE); - csd10->wp_grp_enable = mmcsdGetSlice(csd, MMCSD_CSD_10_WP_GRP_ENABLE_SLICE); - csd10->wp_grp_size = mmcsdGetSlice(csd, MMCSD_CSD_10_WP_GRP_SIZE_SLICE); - csd10->write_bl_len = mmcsdGetSlice(csd, MMCSD_CSD_10_WRITE_BL_LEN_SLICE); - csd10->write_bl_partial = mmcsdGetSlice(csd, MMCSD_CSD_10_WRITE_BL_PARTIAL_SLICE); - csd10->write_blk_misalign = mmcsdGetSlice(csd, MMCSD_CSD_10_WRITE_BLK_MISALIGN_SLICE); + csd = sdcp->csd; + csd10->c_size = _mmcsd_get_slice(csd, MMCSD_CSD_10_C_SIZE_SLICE); + csd10->c_size_mult = _mmcsd_get_slice(csd, MMCSD_CSD_10_C_SIZE_MULT_SLICE); + csd10->ccc = _mmcsd_get_slice(csd, MMCSD_CSD_10_CCC_SLICE); + csd10->copy = _mmcsd_get_slice(csd, MMCSD_CSD_10_COPY_SLICE); + csd10->crc = _mmcsd_get_slice(csd, MMCSD_CSD_10_CRC_SLICE); + csd10->csd_structure = _mmcsd_get_slice(csd, MMCSD_CSD_10_CSD_STRUCTURE_SLICE); + csd10->dsr_imp = _mmcsd_get_slice(csd, MMCSD_CSD_10_DSR_IMP_SLICE); + csd10->erase_blk_en = _mmcsd_get_slice(csd, MMCSD_CSD_10_ERASE_BLK_EN_SLICE); + csd10->erase_sector_size = _mmcsd_get_slice(csd, MMCSD_CSD_10_ERASE_SECTOR_SIZE_SLICE); + csd10->file_format = _mmcsd_get_slice(csd, MMCSD_CSD_10_FILE_FORMAT_SLICE); + csd10->file_format_grp = _mmcsd_get_slice(csd, MMCSD_CSD_10_FILE_FORMAT_GRP_SLICE); + csd10->nsac = _mmcsd_get_slice(csd, MMCSD_CSD_10_NSAC_SLICE); + csd10->perm_write_protect = _mmcsd_get_slice(csd, MMCSD_CSD_10_PERM_WRITE_PROTECT_SLICE); + csd10->r2w_factor = _mmcsd_get_slice(csd, MMCSD_CSD_10_R2W_FACTOR_SLICE); + csd10->read_bl_len = _mmcsd_get_slice(csd, MMCSD_CSD_10_READ_BL_LEN_SLICE); + csd10->read_bl_partial = _mmcsd_get_slice(csd, MMCSD_CSD_10_READ_BL_PARTIAL_SLICE); + csd10->read_blk_misalign = _mmcsd_get_slice(csd, MMCSD_CSD_10_READ_BLK_MISALIGN_SLICE); + csd10->taac = _mmcsd_get_slice(csd, MMCSD_CSD_10_TAAC_SLICE); + csd10->tmp_write_protect = _mmcsd_get_slice(csd, MMCSD_CSD_10_TMP_WRITE_PROTECT_SLICE); + csd10->tran_speed = _mmcsd_get_slice(csd, MMCSD_CSD_10_TRANS_SPEED_SLICE); + csd10->wp_grp_enable = _mmcsd_get_slice(csd, MMCSD_CSD_10_WP_GRP_ENABLE_SLICE); + csd10->wp_grp_size = _mmcsd_get_slice(csd, MMCSD_CSD_10_WP_GRP_SIZE_SLICE); + csd10->write_bl_len = _mmcsd_get_slice(csd, MMCSD_CSD_10_WRITE_BL_LEN_SLICE); + csd10->write_bl_partial = _mmcsd_get_slice(csd, MMCSD_CSD_10_WRITE_BL_PARTIAL_SLICE); + csd10->write_blk_misalign = _mmcsd_get_slice(csd, MMCSD_CSD_10_WRITE_BLK_MISALIGN_SLICE); } /** @@ -295,37 +292,37 @@ void sdcUnpackCSDv10(const MMCSDBlockDevice *sdcp, * * @api */ -void sdcUnpackCSDv20(const MMCSDBlockDevice *sdcp, - unmacked_sdc_csd_20_t *csd20) { +void _mmcsd_unpack_csd_v20(const MMCSDBlockDevice *sdcp, + unmacked_sdc_csd_20_t *csd20) { const uint32_t *csd; osalDbgCheck(NULL != sdcp); - csd = sdcp->csd; - csd20->c_size = mmcsdGetSlice(csd, MMCSD_CSD_20_C_SIZE_SLICE); - csd20->crc = mmcsdGetSlice(csd, MMCSD_CSD_20_CRC_SLICE); - csd20->ccc = mmcsdGetSlice(csd, MMCSD_CSD_20_CCC_SLICE); - csd20->copy = mmcsdGetSlice(csd, MMCSD_CSD_20_COPY_SLICE); - csd20->csd_structure = mmcsdGetSlice(csd, MMCSD_CSD_20_CSD_STRUCTURE_SLICE); - csd20->dsr_imp = mmcsdGetSlice(csd, MMCSD_CSD_20_DSR_IMP_SLICE); - csd20->erase_blk_en = mmcsdGetSlice(csd, MMCSD_CSD_20_ERASE_BLK_EN_SLICE); - csd20->file_format = mmcsdGetSlice(csd, MMCSD_CSD_20_FILE_FORMAT_SLICE); - csd20->file_format_grp = mmcsdGetSlice(csd, MMCSD_CSD_20_FILE_FORMAT_GRP_SLICE); - csd20->nsac = mmcsdGetSlice(csd, MMCSD_CSD_20_NSAC_SLICE); - csd20->perm_write_protect = mmcsdGetSlice(csd, MMCSD_CSD_20_PERM_WRITE_PROTECT_SLICE); - csd20->r2w_factor = mmcsdGetSlice(csd, MMCSD_CSD_20_R2W_FACTOR_SLICE); - csd20->read_bl_len = mmcsdGetSlice(csd, MMCSD_CSD_20_READ_BL_LEN_SLICE); - csd20->read_bl_partial = mmcsdGetSlice(csd, MMCSD_CSD_20_READ_BL_PARTIAL_SLICE); - csd20->read_blk_misalign = mmcsdGetSlice(csd, MMCSD_CSD_20_READ_BLK_MISALIGN_SLICE); - csd20->erase_sector_size = mmcsdGetSlice(csd, MMCSD_CSD_20_ERASE_SECTOR_SIZE_SLICE); - csd20->taac = mmcsdGetSlice(csd, MMCSD_CSD_20_TAAC_SLICE); - csd20->tmp_write_protect = mmcsdGetSlice(csd, MMCSD_CSD_20_TMP_WRITE_PROTECT_SLICE); - csd20->tran_speed = mmcsdGetSlice(csd, MMCSD_CSD_20_TRANS_SPEED_SLICE); - csd20->wp_grp_enable = mmcsdGetSlice(csd, MMCSD_CSD_20_WP_GRP_ENABLE_SLICE); - csd20->wp_grp_size = mmcsdGetSlice(csd, MMCSD_CSD_20_WP_GRP_SIZE_SLICE); - csd20->write_bl_len = mmcsdGetSlice(csd, MMCSD_CSD_20_WRITE_BL_LEN_SLICE); - csd20->write_bl_partial = mmcsdGetSlice(csd, MMCSD_CSD_20_WRITE_BL_PARTIAL_SLICE); - csd20->write_blk_misalign = mmcsdGetSlice(csd, MMCSD_CSD_20_WRITE_BLK_MISALIGN_SLICE); + csd = sdcp->csd; + csd20->c_size = _mmcsd_get_slice(csd, MMCSD_CSD_20_C_SIZE_SLICE); + csd20->crc = _mmcsd_get_slice(csd, MMCSD_CSD_20_CRC_SLICE); + csd20->ccc = _mmcsd_get_slice(csd, MMCSD_CSD_20_CCC_SLICE); + csd20->copy = _mmcsd_get_slice(csd, MMCSD_CSD_20_COPY_SLICE); + csd20->csd_structure = _mmcsd_get_slice(csd, MMCSD_CSD_20_CSD_STRUCTURE_SLICE); + csd20->dsr_imp = _mmcsd_get_slice(csd, MMCSD_CSD_20_DSR_IMP_SLICE); + csd20->erase_blk_en = _mmcsd_get_slice(csd, MMCSD_CSD_20_ERASE_BLK_EN_SLICE); + csd20->file_format = _mmcsd_get_slice(csd, MMCSD_CSD_20_FILE_FORMAT_SLICE); + csd20->file_format_grp = _mmcsd_get_slice(csd, MMCSD_CSD_20_FILE_FORMAT_GRP_SLICE); + csd20->nsac = _mmcsd_get_slice(csd, MMCSD_CSD_20_NSAC_SLICE); + csd20->perm_write_protect = _mmcsd_get_slice(csd, MMCSD_CSD_20_PERM_WRITE_PROTECT_SLICE); + csd20->r2w_factor = _mmcsd_get_slice(csd, MMCSD_CSD_20_R2W_FACTOR_SLICE); + csd20->read_bl_len = _mmcsd_get_slice(csd, MMCSD_CSD_20_READ_BL_LEN_SLICE); + csd20->read_bl_partial = _mmcsd_get_slice(csd, MMCSD_CSD_20_READ_BL_PARTIAL_SLICE); + csd20->read_blk_misalign = _mmcsd_get_slice(csd, MMCSD_CSD_20_READ_BLK_MISALIGN_SLICE); + csd20->erase_sector_size = _mmcsd_get_slice(csd, MMCSD_CSD_20_ERASE_SECTOR_SIZE_SLICE); + csd20->taac = _mmcsd_get_slice(csd, MMCSD_CSD_20_TAAC_SLICE); + csd20->tmp_write_protect = _mmcsd_get_slice(csd, MMCSD_CSD_20_TMP_WRITE_PROTECT_SLICE); + csd20->tran_speed = _mmcsd_get_slice(csd, MMCSD_CSD_20_TRANS_SPEED_SLICE); + csd20->wp_grp_enable = _mmcsd_get_slice(csd, MMCSD_CSD_20_WP_GRP_ENABLE_SLICE); + csd20->wp_grp_size = _mmcsd_get_slice(csd, MMCSD_CSD_20_WP_GRP_SIZE_SLICE); + csd20->write_bl_len = _mmcsd_get_slice(csd, MMCSD_CSD_20_WRITE_BL_LEN_SLICE); + csd20->write_bl_partial = _mmcsd_get_slice(csd, MMCSD_CSD_20_WRITE_BL_PARTIAL_SLICE); + csd20->write_blk_misalign = _mmcsd_get_slice(csd, MMCSD_CSD_20_WRITE_BLK_MISALIGN_SLICE); } #endif /* HAL_USE_MMC_SPI || HAL_USE_SDC */ diff --git a/os/hal/src/mmc_spi.c b/os/hal/src/mmc_spi.c index 99f3b1f6c..4382005be 100644 --- a/os/hal/src/mmc_spi.c +++ b/os/hal/src/mmc_spi.c @@ -516,7 +516,7 @@ bool mmcConnect(MMCDriver *mmcp) { /* Determine capacity.*/ if (read_CxD(mmcp, MMCSD_CMD_SEND_CSD, mmcp->csd)) goto failed; - mmcp->capacity = mmcsdGetCapacity(mmcp->csd); + mmcp->capacity = _mmcsd_get_capacity(mmcp->csd); if (mmcp->capacity == 0) goto failed; diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index 260c7f861..14976f543 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -306,7 +306,8 @@ static bool sdc_detect_bus_clk(SDCDriver *sdcp, sdcbusclk_t *clk) { uint32_t cmdarg = 0; uint8_t *scratchpad = sdcp->config->scratchpad; - *clk = SDC_CLK_25MHz; /* safe default */ + /* Safe default.*/ + *clk = SDC_CLK_25MHz; /* Use safe default when there is no space for data.*/ if (NULL == scratchpad) @@ -341,12 +342,18 @@ static bool sdc_detect_bus_clk(SDCDriver *sdcp, sdcbusclk_t *clk) { static sdcbusclk_t mmc_detect_bus_clk(SDCDriver *sdcp, sdcbusclk_t *clk) { uint32_t cmdarg; uint32_t resp[1]; + uint8_t *scratchpad = sdcp->config->scratchpad; + + /* Safe default.*/ + *clk = SDC_CLK_25MHz; + + /* Use safe default when there is no space for data.*/ + if (NULL == scratchpad) + return HAL_SUCCESS; cmdarg = mmc_cmd6_construct(MMC_SWITCH_WRITE_BYTE, 185, 1, 0); - if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SWITCH, cmdarg, resp) || - MMCSD_R1_ERROR(resp[0])) - *clk = SDC_CLK_25MHz; - else + if (!(sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_SWITCH, cmdarg, resp) || + MMCSD_R1_ERROR(resp[0]))) *clk = SDC_CLK_50MHz; return HAL_SUCCESS; @@ -574,7 +581,6 @@ void sdcStop(SDCDriver *sdcp) { bool sdcConnect(SDCDriver *sdcp) { uint32_t resp[1]; sdcbusclk_t clk = SDC_CLK_25MHz; - uint8_t *scratchpad = sdcp->config->scratchpad; osalDbgCheck(sdcp != NULL); osalDbgAssert((sdcp->state == BLK_ACTIVE) || (sdcp->state == BLK_READY), @@ -628,11 +634,30 @@ bool sdcConnect(SDCDriver *sdcp) { sdc_lld_set_data_clk(sdcp, clk); /* Reads extended CSD if needed and possible.*/ - if (NULL != scratchpad && - SDC_MODE_CARDTYPE_MMC == (sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) && - mmcsdGetSlice(sdcp->csd, MMCSD_CSD_MMC_CSD_STRUCTURE_SLICE) > 1) { - if(sdc_lld_read_special(sdcp, scratchpad, 512, MMCSD_CMD_SEND_EXT_CSD, 0)) - goto failed; + if (SDC_MODE_CARDTYPE_MMC == (sdcp->cardmode & SDC_MODE_CARDTYPE_MASK)) { + + /* The card is a MMC, checking if it is a large device.*/ + if (_mmcsd_get_slice(sdcp->csd, MMCSD_CSD_MMC_CSD_STRUCTURE_SLICE) > 1) { + uint8_t *ext_csd = sdcp->config->scratchpad; + + /* Size detection requires the buffer.*/ + if (NULL == ext_csd) + goto failed; + + if(sdc_lld_read_special(sdcp, ext_csd, 512, MMCSD_CMD_SEND_EXT_CSD, 0)) + goto failed; + + /* Capacity from the EXT_CSD.*/ + sdcp->capacity = _mmcsd_get_capacity_ext(ext_csd); + } + else { + /* Capacity from the normal CSD.*/ + sdcp->capacity = _mmcsd_get_capacity(sdcp->csd); + } + } + else { + /* The card is an SDC, capacity from the normal CSD.*/ + sdcp->capacity = _mmcsd_get_capacity(sdcp->csd); } /* Block length fixed at 512 bytes.*/ @@ -641,15 +666,6 @@ bool sdcConnect(SDCDriver *sdcp) { MMCSD_R1_ERROR(resp[0])) goto failed; - /* Determine capacity.*/ - if (SDC_MODE_CARDTYPE_MMC == (sdcp->cardmode & SDC_MODE_CARDTYPE_MASK)) - sdcp->capacity = mmcsdGetCapacityMMC(sdcp->csd, scratchpad); - else - sdcp->capacity = mmcsdGetCapacity(sdcp->csd); - - if (sdcp->capacity == 0) - goto failed; - /* Switches to wide bus mode.*/ switch (sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) { case SDC_MODE_CARDTYPE_SDV11: diff --git a/os/hal/templates/sdc_lld.h b/os/hal/templates/sdc_lld.h index 43e48afc0..4828149d2 100644 --- a/os/hal/templates/sdc_lld.h +++ b/os/hal/templates/sdc_lld.h @@ -78,7 +78,14 @@ typedef struct SDCDriver SDCDriver; * @note It could be empty on some architectures. */ typedef struct { - uint32_t dummy; + /** + * @brief Working area for memory consuming operations. + * @note It is mandatory for detecting MMC cards bigger than 2GB else it + * can be @p NULL. + * @note Memory pointed by this buffer is only used by @p sdcConnect(), + * afterward it can be reused for other purposes. + */ + uint8_t *scratchpad; } SDCConfig; /** -- cgit v1.2.3