Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eMMC/MMC support for ESP32 #1941

Closed
wants to merge 3 commits into from
Closed

Conversation

starlino
Copy link
Contributor

@starlino starlino commented May 9, 2018

To test this you can use a eMMC to SD adapter and thus connect to a standard SD card slot.

( No need to wait for integrated esp32 eMMC boards )

I tested with following eMMC to SD adapter boards

  1. Micron Chip on mmc+ adapter board
    https://www.m-pression.com/solutions/boards/mmcplus
    https://www.mouser.com/ProductDetail/Mpression/MFSUSANOEMMC?qs=%2fha2pyFadugEKeD5BFVzYhxAOG8O98MMn%252bx6aKXPpVs%3d

  2. DIY solution with Sandisk chip:
    https://intelligenttoasters.blog/2017/01/29/retro-cpc-dongle-part-18/

  3. Kingston ( EMMC04G-M627-ADP, EMMC08G-M325-ADP)
    Available through sales representatives only:
    https://www.kingston.com/us/embedded/emmc

@CLAassistant
Copy link

CLAassistant commented May 9, 2018

CLA assistant check
All committers have signed the CLA.

Copy link
Member

@igrr igrr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing all this work @starlino! I haven't tested this yet, just commented on the most obvious things.

@@ -120,6 +120,9 @@ typedef struct {
#define SDMMC_HOST_FLAG_4BIT BIT(1) /*!< host supports 4-line SD and MMC protocol */
#define SDMMC_HOST_FLAG_8BIT BIT(2) /*!< host supports 8-line MMC protocol */
#define SDMMC_HOST_FLAG_SPI BIT(3) /*!< host supports SPI protocol */
#define SDMMC_HOST_MMC_CARD BIT(8) /*!< card in MMC mode (SD otherwise) */
#define SDMMC_HOST_IO_CARD BIT(9) /*!< card in IO mode (SD moe only) */
#define SDMMC_HOST_MEM_CARD BIT(10) /*!< card in memory mode (SD or MMC) */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SDMMC_HOST_ flags represent host capabilities, not card properties. Please add the bit you need into sdmmc_card_t, next to is_mem and is_sdio.

@@ -25,6 +25,7 @@
#include "sdmmc_cmd.h"
#include "sys/param.h"
#include "soc/soc_memory_layout.h"
#include "soc/sdmmc_struct.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally the protocol layer should not know about host registers. Can this be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed

@@ -191,6 +196,17 @@ esp_err_t sdmmc_card_init(const sdmmc_host_t* config, sdmmc_card_t* card)

/* Send SEND_OP_COND (ACMD41) command to the card until it becomes ready. */
err = sdmmc_send_cmd_send_op_cond(card, host_ocr, &card->ocr);

//if time-out try switching from SD to MMC and vice-versa
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please convert indentation to be the same as surrounding code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

/* sdmmc_mem_mmc_init */
int width, value;
int card_type;
int speed = 20000;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This default value should preferably be a named constant (SDMMC_FREQ_DEFAULT)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

//malloc(size) on esp32 is same as heap_caps_malloc(size, MALLOC_CAP_8BIT)
//!!!remember to free(ext_csd) before all return-s in this block !!!
#define EXT_CSD_SIZE 512
uint8_t* ext_csd = malloc(EXT_CSD_SIZE);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are passing this buffer to the host driver, it might need to be in DMA-capable memory, so heap_caps_malloc with MALLOC_CAP_DMA would be better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

sectors = (ext_csd[EXT_CSD_SEC_COUNT + 0] << 0)
| (ext_csd[EXT_CSD_SEC_COUNT + 1] << 8)
| (ext_csd[EXT_CSD_SEC_COUNT + 2] << 16)
| (ext_csd[EXT_CSD_SEC_COUNT + 3] << 24);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that decoding of ext_csd is scattered across this MMC handling code block. How about introducing a helper function for decoding ext_csd, calling this function once ext_csd is read, and freeing the ext_csd? That would help reduce complexity related to freeing ext_csd. You can store decoded information in the card structure (see how this is done with CSD et al).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can do it this way , although that would be a major refactor and would need a lot of testing to cover all cases.
I would suggest taking this entire mmc initialization code block in a separate function since sdmmc_card_init has grown too big.

I noticed 'goto out' is used in situations where memory needs to be freed eventually. I think a single goto per function is OK and in fact is used extensively in this repository:
https://github.com/espressif/esp-idf/search?utf8=%E2%9C%93&q=goto&type=

free(ext_csd); //done with ext_csd
}

}else{ //SD CARD
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add spaces between keywords and braces

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -539,6 +715,8 @@ static esp_err_t sdmmc_send_cmd_send_if_cond(sdmmc_card_t* card, uint32_t ocr)

static esp_err_t sdmmc_send_cmd_send_op_cond(sdmmc_card_t* card, uint32_t ocr, uint32_t *ocrp)
{
esp_err_t err;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation here as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

if (ptr == NULL) {
error = ESP_ERR_NO_MEM;
} else {
memset(&cmd, 0, sizeof(cmd));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation here as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

sdmmc_command_t cmd = {
.opcode = SD_APP_SET_BUS_WIDTH,
.flags = SCF_RSP_R1 | SCF_CMD_AC,
.arg = (width == 4) ? SD_ARG_BUS_WIDTH_4 : SD_ARG_BUS_WIDTH_1
.arg = (width == 4) ? SD_ARG_BUS_WIDTH_4 : SD_ARG_BUS_WIDTH_1,
.data = ignored,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't find a reference that SET_BUS_WIDTH is a data transfer command, could you explain why this is needed?

Copy link
Contributor Author

@starlino starlino May 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean SD_APP_SET_BUS_WIDTH ? Looking at Jeded documentation it looks like bus width is set with the SWITCH command , indeed SD_APP_SET_BUS_WIDTH = SD_SEND_SWITCH_FUNC = CMD6

igrr pushed a commit that referenced this pull request Aug 30, 2018
Merges #1941
Previous work in #590
@igrr
Copy link
Member

igrr commented Aug 31, 2018

Cherry-picked as 3834647 with subsequent changes in de42d99 (general sdmmc refactoring), 78fab8a (DDR support), b7e5b28 (tests), da34e3e (documentation).

Thanks again @starlino for putting this together and @jsarrett for the initial work in #590!

@igrr igrr closed this Aug 31, 2018
@igrr igrr removed their assignment Aug 31, 2018
catalinio pushed a commit to catalinio/pycom-esp-idf that referenced this pull request Jun 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants