MMC SPI on the STM32L476RG not working...

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: RoccoMarco, barthess

BMWPower
Posts: 24
Joined: Mon Oct 24, 2016 10:27 pm
Has thanked: 1 time
Been thanked: 2 times

MMC SPI on the STM32L476RG not working...

Postby BMWPower » Mon May 21, 2018 10:47 pm

I am trying to get the MMC_SPI (SPI not SDC) working on the STM32L476RG + WaveShare board.

When I use this code I get a respons on my SPI1 .. [testing SPI1]

Code: Select all

/*
 * SPI bus contender 1.
 */
static THD_WORKING_AREA(spi_thread_1_wa, 256);
static THD_FUNCTION(spi_thread_1, p) {

  (void)p;
  chRegSetThreadName("SPI thread 1");
  while (true) {
    unsigned i;

    /* Bush acquisition and SPI reprogramming.*/
    spiAcquireBus(&SPID1);
    spiStart(&SPID1, &hs_spicfg1);

    /* Preparing data buffer and flushing cache.*/
    for (i = 0; i < SPI_BUFFERS_SIZE; i++)
      txbuf[i] = (uint8_t)i;

    /* Slave selection and data exchange.*/
    spiSelect(&SPID1);
    spiExchange(&SPID1, SPI_BUFFERS_SIZE, txbuf, rxbuf);
    spiUnselect(&SPID1);

#if defined(SPI_LOOPBACK)
    if (memcmp(txbuf, rxbuf, SPI_BUFFERS_SIZE) != 0)
      chSysHalt("loopback failure");
#endif

    /* Releasing the bus.*/
    spiReleaseBus(&SPID1);
  }
}


But when I am not running this thread and use the code below I get nothing... the shell is working and the command tree gives back: File System not mounted

But on my logic analyzer I see no electrical respons or signals... what can be wrong? My board.h is changed to SPI1 and the pins:
PB5 [ALT.FUNC 5] = MOSI, PB4 [5] = MISO, PB3 [5] = CLS/SCK, PA15 [analog and tried AF:5] = NSS/CS

Code: Select all

/*
    ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

#include <stdio.h>
#include <string.h>

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

#include "chprintf.h"
#include "evtimer.h"
#include "shell.h"

#include "rt_test_root.h"
#include "oslib_test_root.h"
#include "cands.h"
#include "i2cds.h"

#include "ff.h"

#define MAX_SPI_BITRATE    100
#define MIN_SPI_BITRATE    250

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

#define SPI_BUFFERS_SIZE    128U

static uint8_t txbuf[SPI_BUFFERS_SIZE];
static uint8_t rxbuf[SPI_BUFFERS_SIZE];

static BaseSequentialStream * chp = (BaseSequentialStream*) &SD2;

/*===========================================================================*/
/* Card insertion monitor.                                                   */
/*===========================================================================*/

#define POLLING_INTERVAL                10
#define POLLING_DELAY                   10

/**
 * @brief   Card monitor timer.
 */
static virtual_timer_t tmr;

/**
 * @brief   Debounce counter.
 */
static unsigned cnt;

/**
 * @brief   Card event sources.
 */
static event_source_t inserted_event, removed_event;

/**
 * @brief   Insertion monitor timer callback function.
 *
 * @param[in] p         pointer to the @p BaseBlockDevice object
 *
 * @notapi
 */
static void tmrfunc(void *p) {
  BaseBlockDevice *bbdp = p;

  chSysLockFromISR();
  if (cnt > 0) {
    if (blkIsInserted(bbdp)) {
      if (--cnt == 0) {
        chEvtBroadcastI(&inserted_event);
      }
    }
    else
      cnt = POLLING_INTERVAL;
  }
  else {
    if (!blkIsInserted(bbdp)) {
      cnt = POLLING_INTERVAL;
      chEvtBroadcastI(&removed_event);
    }
  }
  chVTSetI(&tmr, TIME_MS2I(POLLING_DELAY), tmrfunc, bbdp);
  chSysUnlockFromISR();
}

/**
 * @brief   Polling monitor start.
 *
 * @param[in] p         pointer to an object implementing @p BaseBlockDevice
 *
 * @notapi
 */
static void tmr_init(void *p) {

  chEvtObjectInit(&inserted_event);
  chEvtObjectInit(&removed_event);
  chEvtObjectInit(&shell_terminated);
  chSysLock();
  cnt = POLLING_INTERVAL;
  chVTSetI(&tmr, TIME_MS2I(POLLING_DELAY), tmrfunc, p);
  chSysUnlock();
}

/*===========================================================================*/
/* FatFs related.                                                            */
/*===========================================================================*/

/**
 * @brief FS object.
 */
FATFS MMC_FS;

/**
 * MMC driver instance.
 */
MMCDriver MMCD1;

/* Maximum speed SPI configuration (__MHz, NCPHA=1, CPOL=0).*/
static SPIConfig hs_spicfg = {
  NULL,
  GPIOA,
  GPIOA_PIN15,
  SPI_CR1_BR_0|SPI_CR1_CPHA | SPI_CR1_CPOL,
  2
};

/* Low speed SPI configuration (192kHz, NCPHA=1, CPOL=0).*/
static SPIConfig ls_spicfg = {
  NULL,
  GPIOA,
  GPIOA_PIN15,
  SPI_CR1_BR_2 | SPI_CR1_BR_1|SPI_CR1_BR_0|SPI_CR1_CPHA | SPI_CR1_CPOL,
  254
};

/* MMC/SD over SPI driver configuration.*/
static MMCConfig mmccfg = {&SPID1, &ls_spicfg, &hs_spicfg};
/**
 * @brief FS object.
 */
static FATFS SDC_FS;

/* FS mounted and ready.*/
static bool fs_ready = FALSE;

/* Generic large buffer.*/
static uint8_t fbuff[1024];

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

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

/*===========================================================================*/
/* Command line related.                                                     */
/*===========================================================================*/

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)MMCSD_BLOCK_SIZE);
  fbuff[0] = 0;
  scan_files(chp, (char *)fbuff);
}

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, NULL);
  chprintf(chp, "core free memory : %u bytes\r\n", chCoreGetStatusX());
  chprintf(chp, "heap fragments   : %u\r\n", n);
  chprintf(chp, "heap free total  : %u bytes\r\n", size);
}

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

  (void)argv;
  if (argc > 0) {
    chprintf(chp, "Usage: sic\r\n");
    return;
  }
 
  chprintf(chp, "Sending IC \r\n");
  //send_msgic(chp, 1);
}

static const ShellCommand commands[] = {
  {"mem", cmd_mem},
  {"sic", cmd_sendic},
  {"tree", cmd_tree},
  {NULL, NULL}
};

/*
* Shell configuration for the serial protocol and port
*/

static const ShellConfig shell_cfg1 = {
  (BaseSequentialStream *)&SD2, // --> WHEN USING USART2
  //(BaseSequentialStream *)&SDU1,
  commands
};

/*
 * Green LED blinker thread, times are in milliseconds.
 */
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {

  (void)arg;
  chRegSetThreadName("blinker");
  while (true) {
    palClearLine(LINE_LED_GREEN);
    chThdSleepMilliseconds(500);
    palSetLine(LINE_LED_GREEN);
    chThdSleepMilliseconds(500);
  }
}

/*===========================================================================*/
/* Main and generic code.                                                    */
/*===========================================================================*/

static thread_t *shelltp = NULL;

/*
 * Card insertion event.
 */
static void InsertHandler(eventid_t id) {
  FRESULT err;

  (void)id;
  /*
   * On insertion SDC initialization and FS mount.
   */
#if HAL_USE_SDC
  if (sdcConnect(&SDCD1))
#else
  if (mmcConnect(&MMCD1))
#endif
    return;

  err = f_mount(&SDC_FS, "/", 1);
  if (err != FR_OK) {
#if HAL_USE_SDC
    sdcDisconnect(&SDCD1);
#else
    mmcDisconnect(&MMCD1);
#endif
    return;
  }
  fs_ready = TRUE;
}

/*
 * Card removal event.
 */
static void RemoveHandler(eventid_t id) {

  (void)id;
#if HAL_USE_SDC
    sdcDisconnect(&SDCD1);
#else
    mmcDisconnect(&MMCD1);
#endif
  fs_ready = FALSE;
}

/*
 * Shell exit event.
 */
static void ShellHandler(eventid_t id) {

  (void)id;
  if (chThdTerminatedX(shelltp)) {
    chThdRelease(shelltp);
    shelltp = NULL;
  }
}

static const SPIConfig hs_spicfg1 = {
  false,
  NULL,
  GPIOA,
  GPIOA_PIN15,
  SPI_CR1_CPOL | SPI_CR1_BR_0,
  SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0
};

/*
 * SPI bus contender 1.
 */
static THD_WORKING_AREA(spi_thread_1_wa, 256);
static THD_FUNCTION(spi_thread_1, p) {

  (void)p;
  chRegSetThreadName("SPI thread 1");
  while (true) {
    unsigned i;

    /* Bush acquisition and SPI reprogramming.*/
    spiAcquireBus(&SPID1);
    spiStart(&SPID1, &hs_spicfg1);

    /* Preparing data buffer and flushing cache.*/
    for (i = 0; i < SPI_BUFFERS_SIZE; i++)
      txbuf[i] = (uint8_t)i;

    /* Slave selection and data exchange.*/
    spiSelect(&SPID1);
    spiExchange(&SPID1, SPI_BUFFERS_SIZE, txbuf, rxbuf);
    spiUnselect(&SPID1);

#if defined(SPI_LOOPBACK)
    if (memcmp(txbuf, rxbuf, SPI_BUFFERS_SIZE) != 0)
      chSysHalt("loopback failure");
#endif

    /* Releasing the bus.*/
    spiReleaseBus(&SPID1);
  }
}

/*
 * Application entry point.
 */
int main(void) {
  static const evhandler_t evhndl[] = {
    InsertHandler,
    RemoveHandler,
    ShellHandler
  };
  event_listener_t el0, el1, el2;

  thread_t *shelltp = NULL;
  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * Activates the serial driver 2 using the driver default configuration.
   */
  sdStart(&SD2, NULL);

  /*
   * Shell manager initialization.
   */
  shellInit();

  /*
   * Initializes the MMC driver to work with SPI1 on the STM32L476RG.
   */
 
  palSetPad(GPIOA, 15); //--> NSS/CS activate
  //palSetPadMode(GPIOA, GPIOA_PIN15, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGH );       /* NSS/CS      */
  palSetPadMode(GPIOA, GPIOA_PIN15, PAL_MODE_OUTPUT_PUSHPULL);       /* NSS/CS      */
  palSetPadMode(GPIOB, GPIOB_PIN3, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGH );       /* SCK.     */
  palSetPadMode(GPIOB, GPIOB_PIN4, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGH );       /* MISO.    */
  palSetPadMode(GPIOB, GPIOB_PIN5, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_HIGH );       /* MOSI.    */

 
  /*
   * Initializes the MMC driver to work with SPI3.
   */
  mmcObjectInit(&MMCD1);
  mmcStart(&MMCD1, &mmccfg);


  /*
   * Creates the blinker thread.
   */
 chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);

 /*
   * Creates the test SPI1 thread. --> Is working
   */
  //chThdCreateStatic(spi_thread_1_wa, sizeof(spi_thread_1_wa), NORMALPRIO + 1, spi_thread_1, NULL);
 
  /*
   * Activates the card insertion monitor.
   */
  tmr_init(&MMCD1);

  //i2cBusReset(chp);
  //initI2CDs(chp);
  //initCANDS(chp);
  //initI2CDs(chp);
  //initSSD1306(chp);

  //initICUDs(chp);
  //initBTE(chp);

  chEvtRegister(&inserted_event, &el0, 0);
  chEvtRegister(&removed_event, &el1, 1);
  chEvtRegister(&shell_terminated, &el2, 2);

  /*
   * Normal main() thread activity, in this demo it does nothing except
   * sleeping in a loop and check the button state.
   */
  /* main loop */

  while (true) {
    //readICU(chp);
    if (!shelltp) {
      shelltp = chThdCreateFromHeap(NULL, SHELL_WA_SIZE,
                                    "shell", NORMALPRIO + 1,
                                    shellThread, (void *)&shell_cfg1);
    }
    chprintf(chp, ".\r\n");
    chEvtDispatch(evhndl, chEvtWaitOneTimeout(ALL_EVENTS, TIME_MS2I(500)));
  }
}

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: MMC SPI on the STM32L476RG not working...

Postby Giovanni » Tue May 22, 2018 7:21 am

Is the card insertion detected? put breakpoints. There is detection code to be added to board.c.

Giovanni

BMWPower
Posts: 24
Joined: Mon Oct 24, 2016 10:27 pm
Has thanked: 1 time
Been thanked: 2 times

Re: MMC SPI on the STM32L476RG not working...

Postby BMWPower » Tue May 22, 2018 8:22 pm

Added code in board.c


Code: Select all

static bool last_status = FALSE;

  if (blkIsTransferring(mmcp))
    return last_status;
  return last_status = (bool)palReadPad(GPIOA, GPIOA_PIN15);



I put a debug line 292:

Then it hits the event (this is working when I reset the board... but not when I insert the card...). And i step through till it dies.....
Info : halted: PC: 0x08000c60


Code: Select all

SVC_Handler () at ../../../os/common/ports/ARMCMx/chcore_v7m.c:79
79        __set_PSP((uint32_t)ctxp);
(gdb) s
__set_PSP () at ../../../os/common/ext/ARM/CMSIS/Core/Include/cmsis_gcc.h:276
276       __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : );
(gdb) s
SVC_Handler () at ../../../os/common/ports/ARMCMx/chcore_v7m.c:82
82        port_unlock_from_isr();
(gdb) s
port_unlock_from_isr () at ../../../os/common/ports/ARMCMx/chcore_v7m.c:82
82        port_unlock_from_isr();
(gdb) s
port_unlock () at ../../../os/common/ports/ARMCMx/chcore_v7m.c:82
82        port_unlock_from_isr();
(gdb) s
__set_BASEPRI () at ../../../os/common/ext/ARM/CMSIS/Core/Include/cmsis_gcc.h:490
490       __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory");
(gdb) s
_idle_thread.lto_priv.120 (p=0x0) at ../../../os/rt/src/chsys.c:72
72      static void _idle_thread(void *p) {
(gdb) s



And the shell hangs....locks... and the Info output is still filling.... so its not dead??

BMWPower
Posts: 24
Joined: Mon Oct 24, 2016 10:27 pm
Has thanked: 1 time
Been thanked: 2 times

Re: MMC SPI on the STM32L476RG not working...

Postby BMWPower » Tue May 22, 2018 9:14 pm

Update: The InsertHandler is only triggering when I reset the Nucleo with the black button...

breakpoint on 322: [updates some new code with debugging and console output]
322: if (mmcConnect(&MMCD1)) {

p spip->state gives back: SPI_STOP then continue and p spip->state gives back: $2 = SPI_READY

Nothing happens...

After changing the spi_configs to:

Code: Select all

/* Maximum speed SPI configuration (18MHz, CPHA=0, CPOL=0, MSb first).*/
static SPIConfig hs_spicfg = {NULL, GPIOA, GPIOA_PIN15, 0};

/* Low speed SPI configuration (281.250kHz, CPHA=0, CPOL=0, MSb first).*/
static SPIConfig ls_spicfg = {NULL, GPIOA, GPIOA_PIN15,
                              SPI_CR1_BR_2 | SPI_CR1_BR_1};


I get an: _unhandled_exception

So start debugging again:

Code: Select all

__set_PSP () at ../../../os/common/ext/ARM/CMSIS/Core/Include/cmsis_gcc.h:276
276       __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : );
(gdb) s
SVC_Handler () at ../../../os/common/ports/ARMCMx/chcore_v7m.c:82
82        port_unlock_from_isr();
(gdb) s
port_unlock_from_isr () at ../../../os/common/ports/ARMCMx/chcore_v7m.c:82
82        port_unlock_from_isr();
(gdb) s
port_unlock () at ../../../os/common/ports/ARMCMx/chcore_v7m.c:82
82        port_unlock_from_isr();
(gdb) s
__set_BASEPRI () at ../../../os/common/ext/ARM/CMSIS/Core/Include/cmsis_gcc.h:490
490       __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory");
(gdb) s
s_idle_thread.lto_priv.120 (p=0x0) at ../../../os/rt/src/chsys.c:72
72      static void _idle_thread(void *p) {
(gdb) s
s
s


And shell hangs....

BMWPower
Posts: 24
Joined: Mon Oct 24, 2016 10:27 pm
Has thanked: 1 time
Been thanked: 2 times

Re: MMC SPI on the STM32L476RG not working...

Postby BMWPower » Tue May 22, 2018 9:38 pm

Update: Changed everything to SPI2.... same exception...

Code: Select all

VectorFC () at ../../../os/common/startup/ARMCMx/compilers/GCC/vectors.S:767
767              b          _unhandled_exception

BMWPower
Posts: 24
Joined: Mon Oct 24, 2016 10:27 pm
Has thanked: 1 time
Been thanked: 2 times

Re: MMC SPI on the STM32L476RG not working...

Postby BMWPower » Tue May 22, 2018 10:32 pm

Oke I do get some signal on the SPI..... (see attached picture)

The Shell still hangs itself... and the InsertHandler is kicked at reset.... no respons when inserting and removing the card.

The exception is gone after making the PAL_STM32_OSPEED_LOW...

Now (even when hanging) i get at break:
72 static void _idle_thread(void *p) {

Code: Select all

/*
    ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

#include <stdio.h>
#include <string.h>

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

#include "chprintf.h"
#include "evtimer.h"
#include "shell.h"

#include "rt_test_root.h"
#include "oslib_test_root.h"
#include "cands.h"
#include "i2cds.h"

#include "ff.h"

#define MAX_SPI_BITRATE    100
#define MIN_SPI_BITRATE    250

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

#define SPI_BUFFERS_SIZE    128U

static uint8_t txbuf[SPI_BUFFERS_SIZE];
static uint8_t rxbuf[SPI_BUFFERS_SIZE];

static BaseSequentialStream * chp = (BaseSequentialStream*) &SD2;

/*===========================================================================*/
/* Card insertion monitor.                                                   */
/*===========================================================================*/

#define POLLING_INTERVAL                10
#define POLLING_DELAY                   10

/**
 * @brief   Card monitor timer.
 */
static virtual_timer_t tmr;

/**
 * @brief   Debounce counter.
 */
static unsigned cnt;

/**
 * @brief   Card event sources.
 */
static event_source_t inserted_event, removed_event;

/**
 * @brief   Insertion monitor timer callback function.
 *
 * @param[in] p         pointer to the @p BaseBlockDevice object
 *
 * @notapi
 */
static void tmrfunc(void *p) {
  BaseBlockDevice *bbdp = p;

  chSysLockFromISR();
  if (cnt > 0) {
    if (blkIsInserted(bbdp)) {
      if (--cnt == 0) {
        chEvtBroadcastI(&inserted_event);
      }
    }
    else
      cnt = POLLING_INTERVAL;
  }
  else {
    if (!blkIsInserted(bbdp)) {
      cnt = POLLING_INTERVAL;
      chEvtBroadcastI(&removed_event);
    }
  }
  chVTSetI(&tmr, TIME_MS2I(POLLING_DELAY), tmrfunc, bbdp);
  chSysUnlockFromISR();
}

/**
 * @brief   Polling monitor start.
 *
 * @param[in] p         pointer to an object implementing @p BaseBlockDevice
 *
 * @notapi
 */
static void tmr_init(void *p) {

  chEvtObjectInit(&inserted_event);
  chEvtObjectInit(&removed_event);
  chSysLock();
  cnt = POLLING_INTERVAL;
  chVTSetI(&tmr, TIME_MS2I(POLLING_DELAY), tmrfunc, p);
  chSysUnlock();
}

/*===========================================================================*/
/* FatFs related.                                                            */
/*===========================================================================*/

/**
 * @brief FS object.
 */
FATFS MMC_FS;

/**
 * MMC driver instance.
 */
MMCDriver MMCD1;

/* Maximum speed SPI configuration (__MHz, NCPHA=1, CPOL=0).*/
// static SPIConfig hs_spicfg = {
//   NULL,
//   GPIOA,
//   GPIOA_PIN15,
//   SPI_CR1_BR_0|SPI_CR1_CPHA | SPI_CR1_CPOL,
//   2
//};

/* Low speed SPI configuration (192kHz, NCPHA=1, CPOL=0).*/
// static SPIConfig ls_spicfg = {
//   NULL,
//   GPIOA,
//   GPIOA_PIN15,
//   SPI_CR1_BR_2 | SPI_CR1_BR_1|SPI_CR1_BR_0|SPI_CR1_CPHA | SPI_CR1_CPOL,
//   254
// };

#define SPI_BaudRatePrescaler_2         ((uint16_t)0x0000) //  42 MHz      21 MHZ
#define SPI_BaudRatePrescaler_4         ((uint16_t)0x0008) //  21 MHz      10.5 MHz
#define SPI_BaudRatePrescaler_8         ((uint16_t)0x0010) //  10.5 MHz    5.25 MHz
#define SPI_BaudRatePrescaler_16        ((uint16_t)0x0018) //  5.25 MHz    2.626 MHz 
#define SPI_BaudRatePrescaler_32        ((uint16_t)0x0020) //  2.626 MHz   1.3125 MHz
#define SPI_BaudRatePrescaler_64        ((uint16_t)0x0028) //  1.3125 MHz  656.25 KHz
#define SPI_BaudRatePrescaler_128       ((uint16_t)0x0030) //  656.25 KHz  328.125 KHz
#define SPI_BaudRatePrescaler_256       ((uint16_t)0x0038) //  328.125 KHz 164.06 KHz

static SPIConfig hs_spicfg = { NULL, GPIOB, GPIOB_PIN12,SPI_BaudRatePrescaler_2 };
static SPIConfig ls_spicfg = { NULL, GPIOB, GPIOB_PIN12,SPI_BaudRatePrescaler_4 };

/* MMC/SD over SPI driver configuration. -- SPID1 gives errors....unhandled exceptions*/
static MMCConfig mmccfg = {&SPID2, &ls_spicfg, &hs_spicfg};
/**

/* FS mounted and ready.*/
static bool fs_ready = FALSE;

/* Generic large buffer.*/
static uint8_t fbuff[1024];

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

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

/*===========================================================================*/
/* Command line related.                                                     */
/*===========================================================================*/

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)MMCSD_BLOCK_SIZE);
  fbuff[0] = 0;
  scan_files(chp, (char *)fbuff);
}

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, NULL);
  chprintf(chp, "core free memory : %u bytes\r\n", chCoreGetStatusX());
  chprintf(chp, "heap fragments   : %u\r\n", n);
  chprintf(chp, "heap free total  : %u bytes\r\n", size);
}

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

  (void)argv;
  if (argc > 0) {
    chprintf(chp, "Usage: sic\r\n");
    return;
  }
 
  chprintf(chp, "Sending IC \r\n");
  //send_msgic(chp, 1);
}

static const ShellCommand commands[] = {
  {"mem", cmd_mem},
  {"sic", cmd_sendic},
  {"tree", cmd_tree},
  {NULL, NULL}
};

/*
* Shell configuration for the serial protocol and port
*/

static const ShellConfig shell_cfg1 = {
  (BaseSequentialStream *)&SD2, // --> WHEN USING USART2
  //(BaseSequentialStream *)&SDU1,
  commands
};

/*
 * Green LED blinker thread, times are in milliseconds.
 */
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {

  (void)arg;
  chRegSetThreadName("blinker");
  while (true) {
    palClearLine(LINE_LED_GREEN);
    chThdSleepMilliseconds(500);
    palSetLine(LINE_LED_GREEN);
    chThdSleepMilliseconds(500);
  }
}

/*===========================================================================*/
/* Main and generic code.                                                    */
/*===========================================================================*/

static thread_t *shelltp = NULL;

/*
 * Card insertion event.
 */
static void InsertHandler(eventid_t id) {
  FRESULT err;

  (void)id;
  /*
   * On insertion SDC initialization and FS mount.
   */
  chprintf((BaseSequentialStream *)&SD2, "MMC: inserted\r\n");
  /*
   * On insertion MMC initialization and FS mount.
   */
  chprintf((BaseSequentialStream *)&SD2, "MMC: initialization\r\n ");

  if (mmcConnect(&MMCD1)) {
    chprintf((BaseSequentialStream *)&SD2, "failed\r\n");
    return;
  }

  chprintf((BaseSequentialStream *)&SD2, "ok\r\n");
  chprintf((BaseSequentialStream *)&SD2, "FS: mount ");
  err = f_mount(&MMC_FS, "/", 1);
  if (err != FR_OK) {
    chprintf((BaseSequentialStream *)&SD2, "failed\r\n");
    mmcDisconnect(&MMCD1);
    return;
  }
  fs_ready = TRUE;
  chprintf((BaseSequentialStream *)&SD2, "ok\r\n");

}

/*
 * Card removal event.
 */
static void RemoveHandler(eventid_t id) {

  (void)id;
#if HAL_USE_SDC
    sdcDisconnect(&SDCD1);
#else
    mmcDisconnect(&MMCD1);
#endif
  fs_ready = FALSE;
}

/*
 * Shell exit event.
 */
static void ShellHandler(eventid_t id) {

  (void)id;
  if (chThdTerminatedX(shelltp)) {
    chThdRelease(shelltp);
    shelltp = NULL;
  }
}

static const SPIConfig hs_spicfg1 = {
  false,
  NULL,
  GPIOB,
  GPIOB_PIN12,
  SPI_CR1_CPOL | SPI_CR1_BR_0,
  SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0
};

/*
 * SPI bus contender 1.
 */
static THD_WORKING_AREA(spi_thread_1_wa, 256);
static THD_FUNCTION(spi_thread_1, p) {

  (void)p;
  chRegSetThreadName("SPI thread 1");
  while (true) {
    unsigned i;

    /* Bush acquisition and SPI reprogramming.*/
    spiAcquireBus(&SPID2);
    spiStart(&SPID2, &hs_spicfg1);

    /* Preparing data buffer and flushing cache.*/
    for (i = 0; i < SPI_BUFFERS_SIZE; i++)
      txbuf[i] = (uint8_t)i;

    /* Slave selection and data exchange.*/
    spiSelect(&SPID2);
    spiExchange(&SPID2, SPI_BUFFERS_SIZE, txbuf, rxbuf);
    spiUnselect(&SPID2);

#if defined(SPI_LOOPBACK)
    if (memcmp(txbuf, rxbuf, SPI_BUFFERS_SIZE) != 0)
      chSysHalt("loopback failure");
#endif

    /* Releasing the bus.*/
    spiReleaseBus(&SPID2);
  }
}

/*
 * Application entry point.
 */
int main(void) {
  static const evhandler_t evhndl[] = {
    InsertHandler,
    RemoveHandler,
    ShellHandler
  };
  event_listener_t el0, el1, el2;

  thread_t *shelltp = NULL;
  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * Activates the serial driver 2 using the driver default configuration.
   */
  sdStart(&SD2, NULL);

  /*
   * Shell manager initialization.
   */
  shellInit();

  /*
   * Initializes the MMC driver to work with SPI1 on the STM32L476RG.
   */
 
  palSetPad(GPIOB, 12); //--> NSS/CS activate
  //palSetPadMode(GPIOA, GPIOA_PIN15, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGH );       /* NSS/CS      */
  palSetPadMode(GPIOB, GPIOB_PIN12, PAL_MODE_OUTPUT_PUSHPULL);       /* NSS/CS      */
  palSetPadMode(GPIOB, GPIOB_PIN13, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_LOW );       /* SCK.     */
  palSetPadMode(GPIOB, GPIOB_PIN14, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_LOW );       /* MISO.    */
  palSetPadMode(GPIOB, GPIOB_PIN15, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_LOW );       /* MOSI.    */

   /*
   * Initializes the MMC driver to work with SPI3.
   */
  mmcObjectInit(&MMCD1);
  mmcStart(&MMCD1, &mmccfg);

 /*
   * Creates the test SPI1 thread. --> Is working
   */
  //chThdCreateStatic(spi_thread_1_wa, sizeof(spi_thread_1_wa), NORMALPRIO + 1, spi_thread_1, NULL);
 
  /*
   * Activates the card insertion monitor.
   */
  tmr_init(&MMCD1);

  /*
   * Creates the blinker thread.
   */
  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
  //i2cBusReset(chp);
  //initI2CDs(chp);
  //initCANDS(chp);
  //initI2CDs(chp);
  //initSSD1306(chp);

  //initICUDs(chp);
  //initBTE(chp);

  chEvtRegister(&inserted_event, &el0, 0);
  chEvtRegister(&removed_event, &el1, 1);
  chEvtRegister(&shell_terminated, &el2, 2);

  /*
   * Normal main() thread activity, in this demo it does nothing except
   * sleeping in a loop and check the button state.
   */
  /* main loop */
 
  while (true) {
    //readICU(chp);
    chEvtDispatch(evhndl, chEvtWaitOneTimeout(ALL_EVENTS, TIME_MS2I(500)));

    /* Commented this out.... */
    //chEvtDispatch(evhndl, chEvtWaitOne(ALL_EVENTS));
    // if (!shelltp) {
    //   shelltp = chThdCreateFromHeap(NULL, SHELL_WA_SIZE,
    //                                 "shell", NORMALPRIO + 1,
    //                                 shellThread, (void *)&shell_cfg1);
     
    // }

   
   
  }
}
Attachments
spi2.jpg

BMWPower
Posts: 24
Joined: Mon Oct 24, 2016 10:27 pm
Has thanked: 1 time
Been thanked: 2 times

Re: MMC SPI on the STM32L476RG not working...

Postby BMWPower » Tue May 22, 2018 11:10 pm

Update (last today):
I changed something in the shell and it is operational again.... but the InsertHandler is still not responding.... and I have to give an ENTER in the shell to make it active...


ch>
ChibiOS/RT Shell
ch> MMC: inserted
MMC: initialization

ch> mem
core free memory : 88464 bytes
heap fragments : 0
heap free total : 0 bytes
heap free largest: 0 bytes
ch> tree
File System not mounted
ch>

Code: Select all

/*
    ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

#include <stdio.h>
#include <string.h>

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

#include "chprintf.h"
#include "evtimer.h"
#include "shell.h"

#include "rt_test_root.h"
#include "oslib_test_root.h"
#include "cands.h"
#include "i2cds.h"

#include "ff.h"

#define MAX_SPI_BITRATE    100
#define MIN_SPI_BITRATE    250

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

#define SPI_BUFFERS_SIZE    128U

static uint8_t txbuf[SPI_BUFFERS_SIZE];
static uint8_t rxbuf[SPI_BUFFERS_SIZE];

static BaseSequentialStream * chp = (BaseSequentialStream*) &SD2;

/*===========================================================================*/
/* Card insertion monitor.                                                   */
/*===========================================================================*/

#define POLLING_INTERVAL                10
#define POLLING_DELAY                   10

/**
 * @brief   Card monitor timer.
 */
static virtual_timer_t tmr;

/**
 * @brief   Debounce counter.
 */
static unsigned cnt;

/**
 * @brief   Card event sources.
 */
static event_source_t inserted_event, removed_event;

/**
 * @brief   Insertion monitor timer callback function.
 *
 * @param[in] p         pointer to the @p BaseBlockDevice object
 *
 * @notapi
 */
static void tmrfunc(void *p) {
  BaseBlockDevice *bbdp = p;

  /* The presence check is performed only while the driver is not in a
     transfer state because it is often performed by changing the mode of
     the pin connected to the CS/D3 contact of the card, this could disturb
     the transfer.*/
  blkstate_t state = blkGetDriverState(bbdp);
  chSysLockFromISR();
  if ((state != BLK_READING) && (state != BLK_WRITING)) {
    /* Safe to perform the check.*/
    if (cnt > 0) {
      if (blkIsInserted(bbdp)) {
        if (--cnt == 0) {
          chEvtBroadcastI(&inserted_event);
        }
      }
      else
        cnt = POLLING_INTERVAL;
    }
    else {
      if (!blkIsInserted(bbdp)) {
        cnt = POLLING_INTERVAL;
        chEvtBroadcastI(&removed_event);
      }
    }
  }
  chVTSetI(&tmr, TIME_MS2I(POLLING_DELAY), tmrfunc, bbdp);
  chSysUnlockFromISR();
}

/**
 * @brief   Polling monitor start.
 *
 * @param[in] p         pointer to an object implementing @p BaseBlockDevice
 *
 * @notapi
 */
static void tmr_init(void *p) {

  chEvtObjectInit(&inserted_event);
  chEvtObjectInit(&removed_event);
  chSysLock();
  cnt = POLLING_INTERVAL;
  chVTSetI(&tmr, TIME_MS2I(POLLING_DELAY), tmrfunc, p);
  chSysUnlock();
}

/*===========================================================================*/
/* FatFs related.                                                            */
/*===========================================================================*/

/**
 * @brief FS object.
 */
FATFS MMC_FS;

/**
 * MMC driver instance.
 */
MMCDriver MMCD1;

#define SPI_BaudRatePrescaler_2         ((uint16_t)0x0000) //  42 MHz      21 MHZ
#define SPI_BaudRatePrescaler_4         ((uint16_t)0x0008) //  21 MHz      10.5 MHz
#define SPI_BaudRatePrescaler_8         ((uint16_t)0x0010) //  10.5 MHz    5.25 MHz
#define SPI_BaudRatePrescaler_16        ((uint16_t)0x0018) //  5.25 MHz    2.626 MHz 
#define SPI_BaudRatePrescaler_32        ((uint16_t)0x0020) //  2.626 MHz   1.3125 MHz
#define SPI_BaudRatePrescaler_64        ((uint16_t)0x0028) //  1.3125 MHz  656.25 KHz
#define SPI_BaudRatePrescaler_128       ((uint16_t)0x0030) //  656.25 KHz  328.125 KHz
#define SPI_BaudRatePrescaler_256       ((uint16_t)0x0038) //  328.125 KHz 164.06 KHz

static SPIConfig hs_spicfg = { NULL, GPIOB, GPIOB_PIN12,SPI_BaudRatePrescaler_2 };
static SPIConfig ls_spicfg = { NULL, GPIOB, GPIOB_PIN12,SPI_BaudRatePrescaler_4 };

/* MMC/SD over SPI driver configuration. -- SPID1 gives errors....unhandled exceptions*/
static MMCConfig mmccfg = {&SPID2, &ls_spicfg, &hs_spicfg};
/**

/* FS mounted and ready.*/
static bool fs_ready = FALSE;

/* Generic large buffer.*/
static uint8_t fbuff[1024];

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

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

/*===========================================================================*/
/* Command line related.                                                     */
/*===========================================================================*/

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)MMCSD_BLOCK_SIZE);
  fbuff[0] = 0;
  scan_files(chp, (char *)fbuff);
}

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, NULL);
  chprintf(chp, "core free memory : %u bytes\r\n", chCoreGetStatusX());
  chprintf(chp, "heap fragments   : %u\r\n", n);
  chprintf(chp, "heap free total  : %u bytes\r\n", size);
}

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

  (void)argv;
  if (argc > 0) {
    chprintf(chp, "Usage: sic\r\n");
    return;
  }
 
  chprintf(chp, "Sending IC \r\n");
  //send_msgic(chp, 1);
}

static const ShellCommand commands[] = {
  {"mem", cmd_mem},
  {"sic", cmd_sendic},
  {"tree", cmd_tree},
  {NULL, NULL}
};

/*
* Shell configuration for the serial protocol and port
*/

static const ShellConfig shell_cfg1 = {
  (BaseSequentialStream *)&SD2, // --> WHEN USING USART2
  //(BaseSequentialStream *)&SDU1,
  commands
};

/*
 * Green LED blinker thread, times are in milliseconds.
 */
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {

  (void)arg;
  chRegSetThreadName("blinker");
  while (true) {
    palClearLine(LINE_LED_GREEN);
    chThdSleepMilliseconds(500);
    palSetLine(LINE_LED_GREEN);
    chThdSleepMilliseconds(500);
  }
}

/*===========================================================================*/
/* Main and generic code.                                                    */
/*===========================================================================*/

static thread_t *shelltp = NULL;

/*
 * Card insertion event.
 */
static void InsertHandler(eventid_t id) {
  FRESULT err;

  (void)id;
  /*
   * On insertion SDC initialization and FS mount.
   */
  chprintf((BaseSequentialStream *)&SD2, "MMC: inserted\r\n");
  /*
   * On insertion MMC initialization and FS mount.
   */
  chprintf((BaseSequentialStream *)&SD2, "MMC: initialization\r\n ");
  // A little delay
  chThdSleepMilliseconds(100);

  if (mmcConnect(&MMCD1)) {
    chprintf((BaseSequentialStream *)&SD2, "failed\r\n");
    return;
  }

  chprintf((BaseSequentialStream *)&SD2, "ok\r\n");
  chprintf((BaseSequentialStream *)&SD2, "FS: mount ");
  err = f_mount(&MMC_FS, "/", 1);
  if (err != FR_OK) {
    chprintf((BaseSequentialStream *)&SD2, "failed\r\n");
    mmcDisconnect(&MMCD1);
    return;
  }
  fs_ready = TRUE;
  chprintf((BaseSequentialStream *)&SD2, "ok\r\n");

}

/*
 * Card removal event.
 */
static void RemoveHandler(eventid_t id) {

  (void)id;
#if HAL_USE_SDC
    sdcDisconnect(&SDCD1);
#else
    mmcDisconnect(&MMCD1);
#endif
  fs_ready = FALSE;
}

static const SPIConfig hs_spicfg1 = {
  false,
  NULL,
  GPIOB,
  GPIOB_PIN12,
  SPI_CR1_CPOL | SPI_CR1_BR_0,
  SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0
};

/*
 * SPI bus contender 1.
 */
static THD_WORKING_AREA(spi_thread_1_wa, 256);
static THD_FUNCTION(spi_thread_1, p) {

  (void)p;
  chRegSetThreadName("SPI thread 1");
  while (true) {
    unsigned i;

    /* Bush acquisition and SPI reprogramming.*/
    spiAcquireBus(&SPID2);
    spiStart(&SPID2, &hs_spicfg1);

    /* Preparing data buffer and flushing cache.*/
    for (i = 0; i < SPI_BUFFERS_SIZE; i++)
      txbuf[i] = (uint8_t)i;

    /* Slave selection and data exchange.*/
    spiSelect(&SPID2);
    spiExchange(&SPID2, SPI_BUFFERS_SIZE, txbuf, rxbuf);
    spiUnselect(&SPID2);

#if defined(SPI_LOOPBACK)
    if (memcmp(txbuf, rxbuf, SPI_BUFFERS_SIZE) != 0)
      chSysHalt("loopback failure");
#endif

    /* Releasing the bus.*/
    spiReleaseBus(&SPID2);
  }
}

/*
 * Application entry point.
 */
int main(void) {
  static const evhandler_t evhndl[] = {
    InsertHandler,
    RemoveHandler
  };
  event_listener_t el0, el1, el2;

  thread_t *shelltp = NULL;
  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();

  /*
   * Activates the serial driver 2 using the driver default configuration.
   */
  sdStart(&SD2, NULL);

  /*
   * Shell manager initialization.
   */
  shellInit();

  /*
   * Initializes the MMC driver to work with SPI1 on the STM32L476RG.
   */
 
  palSetPad(GPIOB, 12); //--> NSS/CS activate
  //palSetPadMode(GPIOA, GPIOA_PIN15, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGH );       /* NSS/CS      */
  palSetPadMode(GPIOB, GPIOB_PIN12, PAL_MODE_OUTPUT_PUSHPULL);       /* NSS/CS      */
  palSetPadMode(GPIOB, GPIOB_PIN13, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_LOW );       /* SCK.     */
  palSetPadMode(GPIOB, GPIOB_PIN14, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_LOW );       /* MISO.    */
  palSetPadMode(GPIOB, GPIOB_PIN15, PAL_MODE_ALTERNATE(5) | PAL_STM32_OSPEED_LOW );       /* MOSI.    */

   /*
   * Initializes the MMC driver to work with SPI3.
   */
  mmcObjectInit(&MMCD1);
  mmcStart(&MMCD1, &mmccfg);

 /*
   * Creates the test SPI1 thread. --> Is working
   */
  //chThdCreateStatic(spi_thread_1_wa, sizeof(spi_thread_1_wa), NORMALPRIO + 1, spi_thread_1, NULL);
 
  /*
   * Activates the card insertion monitor.
   */
  tmr_init(&MMCD1);

  /*
   * Creates the blinker thread.
   */
  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
  //i2cBusReset(chp);
  //initI2CDs(chp);
  //initCANDS(chp);
  //initI2CDs(chp);
  //initSSD1306(chp);

  //initICUDs(chp);
  //initBTE(chp);

  /*
   * Normal main() thread activity, in this demo it does nothing except
   * sleeping in a loop and listen for events.
   */
  chEvtRegister(&inserted_event, &el0, 0);
  chEvtRegister(&removed_event, &el1, 1);
  while (TRUE) {
    if (!shelltp)
      shelltp = chThdCreateFromHeap(NULL, SHELL_WA_SIZE,
                                     "shell", NORMALPRIO + 1,
                                     shellThread, (void *)&shell_cfg1);
    else if (chThdTerminatedX(shelltp)) {
      chThdRelease(shelltp);    /* Recovers memory of the previous shell. */
      shelltp = NULL;           /* Triggers spawning of a new shell.      */
    }
    chEvtDispatch(evhndl, chEvtWaitOneTimeout(ALL_EVENTS, TIME_MS2I(500)));
  }
  return 0;
}

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: MMC SPI on the STM32L476RG not working...

Postby Giovanni » Wed May 23, 2018 8:31 am

Hi,

Apparently your detection code does not work and does not trigger the FS mount. The debugger is on your side, there isn't much we can do from here.

Giovanni


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 18 guests