0
\$\begingroup\$

I have a custom board using an Atmel SAM G55J (ATSAMG55J19A-AU) and I'm trying to get the SD card reader to work - which is connected to SPI0. I'm using the SD/MMC stack (set for SPI), as well as FatFS, available with ASF.

Following the example/demo code of the ASF's SD/MMC stack for the Atmel SAMG55, I made what I believe to be the necessary defines in order to communicate with the SD card reader throught SPI:

/** Enable SD MMC interface pins through SPI */
#define CONF_BOARD_SD_MMC_SPI

/** SPI slave select MACRO definition */
#define CONF_BOARD_SPI_NPCS0

/** FLEXCOM base address for SPI mode*/
#define BOARD_FLEXCOM_SPI    FLEXCOM0

/** SPI MISO pin definition. */
#define SPI_MISO_GPIO         (PIO_PA9_IDX)
#define SPI_MISO_FLAGS        (IOPORT_MODE_MUX_A)
/** SPI MOSI pin definition. */
#define SPI_MOSI_GPIO         (PIO_PA10_IDX)
#define SPI_MOSI_FLAGS        (IOPORT_MODE_MUX_A)
/** SPI SPCK pin definition. */
#define SPI_SPCK_GPIO         (PIO_PB0_IDX)
#define SPI_SPCK_FLAGS        (IOPORT_MODE_MUX_A)

/** SPI chip select 0 pin definition. */
#define SPI_NPCS0_GPIO        (PIO_PA17_IDX)
#define SPI_NPCS0_FLAGS       (IOPORT_MODE_MUX_A)

/** SPI Card Detect pin definition */
#define SD_MMC_SPI_MEM_CNT          1
#define SD_MMC_0_CD_GPIO            (PIO_PA18_IDX)
#define SD_MMC_0_CD_DIR             (IOPORT_DIR_INPUT)
#define SD_MMC_0_CD_MODE            (IOPORT_MODE_PULLUP)
#define SD_MMC_0_CD_DETECT_VALUE    1
#define SD_MMC_SPI                  SPI0
#define SD_MMC_SPI_0_CS             0
#define SD_MMC_0_CD_PIO_ID          ID_PIOA

In order to setup/initialize the SD card reader I created this:

void setup_peripherals(void)
{
    //Disable watchdog timer
    wdt_disable(WDT);

    ioport_init();  // call before using IOPORT service

    //Enable PIOA clock to detect Card Detect (CD) change
    sysclk_enable_peripheral_clock(ID_PIOA);

    //Setting SPI pins
    ioport_set_pin_peripheral_mode(SPI_MISO_GPIO, SPI_MISO_FLAGS);
    ioport_set_pin_peripheral_mode(SPI_MOSI_GPIO, SPI_MOSI_FLAGS);
    ioport_set_pin_peripheral_mode(SPI_SPCK_GPIO, SPI_SPCK_FLAGS);

    //Setting SD Card Detect pin
    ioport_set_pin_dir(SD_MMC_0_CD_GPIO, IOPORT_DIR_INPUT);
    ioport_set_pin_mode(SD_MMC_0_CD_GPIO, IOPORT_MODE_PULLUP);

    //Setting SPI chip select pin
    ioport_set_pin_peripheral_mode(SPI_NPCS0_GPIO, SPI_NPCS0_FLAGS);

    //Initialize SD MMC stack
    sd_mmc_init();  
}

However, I don't seem to be able to detect that the SD card has been inserted since I get stuck here:

void WaitForSDCard(void)
{
    Ctrl_status status;

    //Wait until SD stack initialized and SD card inserted
    do
    {
        //Check if stack ready
        status = sd_mmc_test_unit_ready(0);

        if (status == CTRL_FAIL)
        {               
            //Wait for a card to be inserted
            while (sd_mmc_check(0) != CTRL_NO_PRESENT)
            {
                //!!!NEEDS A TIME OUT HERE!!!
            }
        }
    } while (status != CTRL_GOOD);
}

This happens because sd_mmc_test_unit_ready(0) keeps returning CTRL_NO_PRESENT, since sd_mmc_check(0) outputs SD_MMC_ERR_NO_CARD.

While I was trying to debug this problem/error I found out that sd_mmc_cards[0].state is initially set to SD_MMC_CARD_STATE_NO_CARD, which seems to be the default value for it. However the sd_mmc_select_slot(0) function changes the state to SD_MMC_CARD_STATE_DEBOUNCE which leads to sd_mmc_test_unit_ready(0) returning CTRL_NO_PRESENT.

Now, from my understanding the Card Detect should work similar to simple switch right? With that in mind, I tried to simply set the CD pin as an input using ioport and checking his level, however it simply returns 1 all the time (with or without card).

Any idea about what I'm doing wrong here?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.