SD card mount issue on F103

This forum is dedicated to feedback, discussions about ongoing or future developments, ideas and suggestions regarding the ChibiOS projects are welcome. This forum is NOT for support.
User avatar
Tectu
Posts: 1225
Joined: Thu May 10, 2012 9:50 am

SD card mount issue on F103

Post by Tectu »

Hey Guys,

It's me, I could need a little help here:

I ported the ARMCM3-STM32F103-FATFS example from the OLIMEX_STM32_P103 to my own board. After compiling and flashing, I can access the shell without any problems. Also the "test" runs successfully.
But when I put in an SD card, nothing happens. I am not sure where the problem is. I put a a line into the InsertHandler() which lights up an LED, when the SD card got plugged in, to be sure that it comes to that point and there's no issue with MMCCP. As suggested, the LED lights up, so I guess, the problem needs to be at mmcConnect(), since the other LED (LED3) dosen't light up (yeah, I like LEDs for debuggin ;-) ).

Can someone tell me, where the problem is?
The only 'big thing' I changed is in my board.c file. My board dosen't support the readout of the write protection, therefore, the function just returns 1 (also tried it with return 0, to be sure, that there is no issue - didn't work too).

here my main.c:

Code: Select all

#include <string.h>
#include "ch.h"
#include "hal.h"
#include "test.h"
#include "shell.h"
#include "evtimer.h"
#include "chprintf.h"
#include "ff.h"

FATFS MMC_FS;
MMCDriver MMCD1;

static bool_t fs_ready = FALSE;
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};
static MMCConfig mmccfg = {&SPID2, &ls_spicfg, &hs_spicfg};
uint8_t fbuff[1024];

static FRESULT scan_files(BaseSequentialStream *chp, char *path) {
     FRESULT res;
     FILINFO fno;
     DIR dir;
     int i;
    char *fn;

     res = f_opendir(&dir, path);
     if (res == FR_OK) {
       i = strlen(path);
       for (;;) {
          res = f_readdir(&dir, &fno);
            if (res != FR_OK || fno.fname[0] == 0)
              break;
            if (fno.fname[0] == '.')
              continue;
            fn = fno.fname;
            if (fno.fattrib & AM_DIR) {
              path[i++] = '/';
              strcpy(&path[i], fn);
              res = scan_files(chp, path);
              if (res != FR_OK)
                   break;
              path[i] = 0;
            } else {
            chprintf(chp, "%s/%s\r\n", path, fn);
            }
       }
     }
     return res;
}

#define SHELL_WA_SIZE   THD_WA_SIZE(2048)
#define TEST_WA_SIZE    THD_WA_SIZE(256)

static void cmd_mem(BaseSequentialStream *chp, int argc, char *argv[]) {
     size_t n, size;

     (void)argv;
     if (argc > 0) {
       chprintf(chp, "Usage: mem\r\n");
       return;
     }
     n = chHeapStatus(NULL, &size);
     chprintf(chp, "core free memory : %u bytes\r\n", chCoreStatus());
     chprintf(chp, "heap fragments   : %u\r\n", n);
     chprintf(chp, "heap free total  : %u bytes\r\n", size);
}

static void cmd_threads(BaseSequentialStream *chp, int argc, char *argv[]) {
     static const char *states[] = {THD_STATE_NAMES};
     Thread *tp;

     (void)argv;
     if (argc > 0) {
       chprintf(chp, "Usage: threads\r\n");
       return;
     }
     chprintf(chp, "    addr    stack prio refs     state time\r\n");
     tp = chRegFirstThread();
     do {
       chprintf(chp, "%.8lx %.8lx %4lu %4lu %9s %lu\r\n",
           (uint32_t)tp, (uint32_t)tp->p_ctx.r13,
            (uint32_t)tp->p_prio, (uint32_t)(tp->p_refs - 1),
            states[tp->p_state], (uint32_t)tp->p_time);
       tp = chRegNextThread(tp);
     } while (tp != NULL);
}

static void cmd_test(BaseSequentialStream *chp, int argc, char *argv[]) {
     Thread *tp;

     (void)argv;
     if (argc > 0) {
       chprintf(chp, "Usage: test\r\n");
       return;
     }
     tp = chThdCreateFromHeap(NULL, TEST_WA_SIZE, chThdGetPriority(), TestThread, chp);
     if (tp == NULL) {
       chprintf(chp, "out of memory\r\n");
       return;
     }
     chThdWait(tp);
}

static void cmd_tree(BaseSequentialStream *chp, int argc, char *argv[]) {
     FRESULT err;
     uint32_t clusters;
     FATFS *fsp;

     (void)argv;
     if (argc > 0) {
       chprintf(chp, "Usage: tree\r\n");
       return;
     }
     if (!fs_ready) {
       chprintf(chp, "File System not mounted\r\n");
       return;
     }
     err = f_getfree("/", &clusters, &fsp);
     if (err != FR_OK) {
       chprintf(chp, "FS: f_getfree() failed\r\n");
       return;
     }   
     chprintf(chp, "FS: %lu free clusters, %lu sectors per cluster, %lu bytes free\r\n",
           clusters, (uint32_t)MMC_FS.csize,
           clusters * (uint32_t)MMC_FS.csize * (uint32_t)MMC_SECTOR_SIZE);
     fbuff[0] = 0;
     scan_files(chp, (char *)fbuff);
}

static const ShellCommand commands[] = {
     {"mem", cmd_mem},
     {"threads", cmd_threads},
     {"test", cmd_test},
     {"tree", cmd_tree},
     {NULL, NULL}
};

static const ShellConfig shell_cfg1 = {
   (BaseSequentialStream *)&SD2, commands
};

static WORKING_AREA(waThread1, 128);
static msg_t Thread1(void *arg) {
   (void)arg;
   chRegSetThreadName("blinker");
   while(TRUE) {
      palTogglePad(IOPORT4, GPIOD_LED1);
      if(fs_ready)
         chThdSleepMilliseconds(100);
      else
         chThdSleepMilliseconds(500);
   }
   return 0;
}

static void InsertHandler(eventid_t id) {
   FRESULT err;
   (void)id;

   palSetPad(GPIOD, GPIOD_LED2);

   if (mmcConnect(&MMCD1)) {
      palSetPad(GPIOD, GPIOD_LED3);
      return;
   }
   err = f_mount(0, &MMC_FS);
   if (err != FR_OK) {
      mmcDisconnect(&MMCD1);
      return;
   }

   fs_ready = TRUE;
}

static void RemoveHandler(eventid_t id) {
   (void)id;
   palClearPad(GPIOD, GPIOD_LED2);
   fs_ready = FALSE;
}

int main(void) {
     static const evhandler_t evhndl[] = {
       InsertHandler,
       RemoveHandler
     };
     Thread *shelltp = NULL;
     struct EventListener el0, el1;

     halInit();
     chSysInit();
     sdStart(&SD2, NULL);
    shellInit();
 
   palSetPadMode(GPIOB, GPIOB_SPI2NSS, PAL_MODE_OUTPUT_PUSHPULL);
   palSetPad(GPIOB, GPIOB_SPI2NSS);
   mmcObjectInit(&MMCD1);
   mmcStart(&MMCD1, &mmccfg);

     chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);

     chEvtRegister(&MMCD1.inserted_event, &el0, 0);
     chEvtRegister(&MMCD1.removed_event, &el1, 1);
     
   while(TRUE) {
      if(!shelltp)
         shelltp = shellCreate(&shell_cfg1, SHELL_WA_SIZE, NORMALPRIO);
      else if (chThdTerminated(shelltp)) {
         chThdRelease(shelltp);    /* Recovers memory of the previous shell.   */
         shelltp = NULL;           /* Triggers spawning of a new shell.        */
      }
       chEvtDispatch(evhndl, chEvtWaitOne(ALL_EVENTS));
  }
  return 0;
}


my board.h:

Code: Select all

#ifndef _BOARD_H_
#define _BOARD_H_

// Board identifier.
#define BOARD_MY_BOARD
#define BOARD_NAME              "my board"

// Board frequencies.
#define STM32_LSECLK            32768
#define STM32_HSECLK            8000000

// MCU type, supported types are defined in ./os/hal/platforms/hal_lld.h.
#define STM32F10X_HD

// IO pins assignments.
#define GPIOA_BUTTON         8

#define GPIOD_LED1            8
#define GPIOD_LED2            9
#define GPIOD_LED3            10
#define GPIOD_LED4            11

#define GPIOB_SPI2NSS         12
#define GPIOA_MMCCP             4
/*
 * I/O ports initial setup, this configuration is established soon after reset
 * in the initialization code.
 *
 * The digits have the following meaning:
 *   0 - Analog input.
 *   1 - Push Pull output 10MHz.
 *   2 - Push Pull output 2MHz.
 *   3 - Push Pull output 50MHz.
 *   4 - Digital input.
 *   5 - Open Drain output 10MHz.
 *   6 - Open Drain output 2MHz.
 *   7 - Open Drain output 50MHz.
 *   8 - Digital input with PullUp or PullDown resistor depending on ODR.
 *   9 - Alternate Push Pull output 10MHz.
 *   A - Alternate Push Pull output 2MHz.
 *   B - Alternate Push Pull output 50MHz.
 *   C - Reserved.
 *   D - Alternate Open Drain output 10MHz.
 *   E - Alternate Open Drain output 2MHz.
 *   F - Alternate Open Drain output 50MHz.
 * Please refer to the STM32 Reference Manual for details.
 */

#define VAL_GPIOACRL            0x34344B34      /*  PA7...PA0 */
#define VAL_GPIOACRH            0x444334B4      /* PA15...PA8 */
#define VAL_GPIOAODR            0xFFFFFFFF

#define VAL_GPIOBCRL            0x88888888      /*  PB7...PB0 */
#define VAL_GPIOBCRH            0xB4B88888      /* PB15...PB8 */
#define VAL_GPIOBODR            0xFFFFFFFF

#define VAL_GPIOCCRL            0x44848888      /*  PC7...PC0 */
#define VAL_GPIOCCRH            0x88833388      /* PC15...PC8 */
#define VAL_GPIOCODR            0xFFFFFFFF

#define VAL_GPIODCRL            0x33388888      /*  PD7...PD0 */
#define VAL_GPIODCRH            0x33333333      /* PD15...PD8 */
#define VAL_GPIODODR            0xFFFFFFFF

#define VAL_GPIOECRL            0x33333333      /*  PE7...PE0 */
#define VAL_GPIOECRH            0x33333333      /* PE15...PE8 */
#define VAL_GPIOEODR            0xFFFFFFFF

#if !defined(_FROM_ASM_)
#ifdef __cplusplus
extern "C" {
#endif
  void boardInit(void);
#ifdef __cplusplus
}
#endif
#endif /* _FROM_ASM_ */

#endif /* _BOARD_H_ */


and my board.c:

Code: Select all

#include "ch.h"
#include "hal.h"

/**
 * @brief   PAL setup.
 * @details Digital I/O ports static configuration as defined in @p board.h.
 *          This variable is used by the HAL when initializing the PAL driver.
 */
#if HAL_USE_PAL || defined(__DOXYGEN__)
const PALConfig pal_default_config =
{
  {VAL_GPIOAODR, VAL_GPIOACRL, VAL_GPIOACRH},
  {VAL_GPIOBODR, VAL_GPIOBCRL, VAL_GPIOBCRH},
  {VAL_GPIOCODR, VAL_GPIOCCRL, VAL_GPIOCCRH},
  {VAL_GPIODODR, VAL_GPIODCRL, VAL_GPIODCRH},
  {VAL_GPIOEODR, VAL_GPIOECRL, VAL_GPIOECRH},
};
#endif

#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(GPIOA, GPIOA_MMCCP);
}

bool_t mmc_lld_is_write_protected(MMCDriver *mmcp) {

  (void)mmcp;
  return 0;
}
#endif

/*
 * Early initialization code.
 * This initialization must be performed just after stack setup and before
 * any other initialization.
 */
void __early_init(void) {

  stm32_clock_init();
}

void boardInit(void) {
   palClearPad(GPIOD, GPIOD_LED1);
   palClearPad(GPIOD, GPIOD_LED2);
   palClearPad(GPIOD, GPIOD_LED3);
   palClearPad(GPIOD, GPIOD_LED4);
}



I am sure that SPI2NSS is GPIOB Pin 12 on my board.
In the Makefile from the STM32F103-FATFS example, I just changed my board, the linkerscript (STM32F103xE.ld) and the path of the chibios.
I use a SandDisk SD Card Class 2 with 2GB (no sdhc).

~ Tectu
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: SD card mount issue on F103

Post by Giovanni »

If you have a logic analyzer look for the SPI traffic. If not do the LED debugging into mmcConnect() and see at which point it fails.

Consider getting a chap JTAG, even a discovery kit is a free debugger.

Giovanni
User avatar
Tectu
Posts: 1225
Joined: Thu May 10, 2012 9:50 am

Re: SD card mount issue on F103

Post by Tectu »

Hello There,

I don't have any logic analyzer here.

in chibios/os/hal/src/mmc_spi.c, I did inside mmcConnect() (line 491):

Code: Select all

palSetPad(GPIOD, GPIOD_LED2);
    /* SPI mode selection.*/
    i = 0;
    while (TRUE) {
      if (send_command_R1(mmcp, MMCSD_CMD_GO_IDLE_STATE, 0) == 0x01)
        break;
      if (++i >= MMC_CMD0_RETRY)
        return TRUE;
      chThdSleepMilliseconds(10);
    }   
palSetPad(GPIOD, GPIOD_LED3);


LED2 lights up, when I insert a SD card, but LED3 dosen't.
Does that help?

Btw, I would have a working GDB connection now.


~ Tectu
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: SD card mount issue on F103

Post by Giovanni »

The card does not answer to the first command, probably it is an IO pins setup error or an HW error.

Giovanni
User avatar
Tectu
Posts: 1225
Joined: Thu May 10, 2012 9:50 am

Re: SD card mount issue on F103

Post by Tectu »

It works now...

I took a different SD card, and then it worked without any problems... Is this one of these known SD card compatibility issues? I never worked with SD cards before, but I know from reading in forums etc, that all SD cards are a bit different, and when it works with one, it dosen't work with the other, because the manufacturers don't use the standards properly.

Is there a hope to use the other SD card?

Thanks for helping anyways.

~ Tectu
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: SD card mount issue on F103

Post by Giovanni »

Hi,

This is the first one that does not work AFAIK, is it possible it is not SPI-capable?

Giovanni
User avatar
Tectu
Posts: 1225
Joined: Thu May 10, 2012 9:50 am

Re: SD card mount issue on F103

Post by Tectu »

Hello Giovanni,

Well, I am not know how to find that out. That are SD cards from SanDisk, Class 2, 2GB, duo pack.
The one I took now is simply a no-name microSD card with 256MB size, into a microSD to SD card adapter - works without any problems.

To be sure that there is no formatting issue, I formatted ALL three cards new, on the same system with FAT32. After that, still only the microSD card works.
I don't have any other SD card arround, I'll try others in a few hour.

My boad got shipped with a DVD with examples, using stdlib and Keil. Under Windows, I compiled and flashed the example which used an SD card. The two SanDisk cards do work there without any issue.


~ Tectu
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: SD card mount issue on F103

Post by Giovanni »

You could try to make the "slow" SPI clock slower/faster, it is part of the card initialization procedure.

Giovanni
User avatar
Tectu
Posts: 1225
Joined: Thu May 10, 2012 9:50 am

Re: SD card mount issue on F103

Post by Tectu »

Update: Transcend 8GB sdhc class 10 cards works without any problems...
User avatar
Tectu
Posts: 1225
Joined: Thu May 10, 2012 9:50 am

Re: SD card mount issue on F103

Post by Tectu »

Okay, I did a series of tests now, andere here's the result: Every SD card on the picture below does work, BUT NOT the SanDisk on the right side.


Image
Post Reply