STM32F4 Discovery MMC over SPI how to accelerate

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

Moderator: RoccoMarco

Kot_dnz
Posts: 10
Joined: Tue Jan 28, 2014 9:21 am

STM32F4 Discovery MMC over SPI how to accelerate

Post by Kot_dnz »

Dear Guru,

I'm novice in this OS and desk STM32F4Diskovery and ask your help.
I write a LOG module for save my logs to MMC card over SPI2 (target twice per second).
I learned a lot of samples (OS, Japan guru, other) and found good feedback about MMC over CSD or MMC over SPI in DMA mode.
What i have now:

Code: Select all

// Peripherial Clock 42MHz SPI2 SPI3
// Peripherial Clock 84MHz SPI1                                SPI1        SPI2/3
#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, SPI_SD_MODULE_PORT, SPI_SD_MODULE_PIN,
SPI_BaudRatePrescaler_4 };
static SPIConfig ls_spicfg = { NULL, SPI_SD_MODULE_PORT, SPI_SD_MODULE_PIN,
SPI_BaudRatePrescaler_8 };

/* MMC/SD over SPI driver configuration.*/
// don't forget check if STM32_SPI_USE_SPI2 defined and spi has init with correct GPIO in hardware.c
static MMCConfig mmccfg = { &SPID2, &ls_spicfg, &hs_spicfg };

void initMmcCard(void) {
   memset(&errorlineReported, '\0', MAX_LOG_STRING_SIZE);      // zero flash line buffer

   mmcObjectInit(&MMCD1);                  // Initializes an MMC instance.
   mmcStart(&MMCD1, &mmccfg);               // Configures and activates the MMC peripheral.

   addConsoleAction("mmc_mount", &MMCmount);
   addConsoleActionS("mmc_appendToLog", &appendToLog);
   addConsoleAction("mmc_umount", &MMCumount);
   addConsoleAction("mmc_ls", &ff_cmd_dir);
   addConsoleAction("mmc_stat", &ff_cmd_stat);
}


function umount & mount

Code: Select all

/*
 * MMC card umount.
 */
static void MMCumount(void) {
   if (!fs_ready) {
      print("Error: No File system is mounted. \"mmc_mount\" first.\r\n");
      return;
   }
   f_close(&FDLogFile);                  // close file
   mmcDisconnect(&MMCD1);                  // Brings the driver in a state safe for card removal.
   f_mount(NULL, fDisk, 0);                  // FATFS: Unregister work area prior to discard it
   memset(&FDLogFile, 0, sizeof(FIL));         // clear FDLogFile
   fs_ready = FALSE;                     // status = false
   print("MMC/SD card removed.\r\n");
}

/*
 * MMC card mount.
 */
static void MMCmount(void) {

   if (fs_ready) {
      print("Error: Already mounted. \"mmc_umount\" first\r\n");
      return;
   }
   // start to initialize MMC/SD
   if(MMCD1.state == BLK_ACTIVE) {
         mmcConnect(&MMCD1);
         chThdSleepMilliseconds(100);
   }
   if (MMCD1.state == BLK_READY) {      // Performs the initialization procedure on the inserted card.
      memset(&MMC_FS, 0, sizeof(FATFS));            // clear the memory
      FRESULT err = f_mount(&MMC_FS, fDisk, 0);         // Initialize logical drive
      if (err == FR_OK) {                        // if Ok - FS now mounted
         memset(&FDLogFile, 0, sizeof(FIL));      // clear the memory
         err = f_open(&FDLogFile, LogFileName, FA_WRITE | FA_OPEN_ALWAYS );   // open for write & Create if not exist
         if (err == FR_OK || err == FR_EXIST) {
            err = f_lseek(&FDLogFile, f_size(&FDLogFile)); // SEEK to end of the file to append data
            if (err) {
               printError("Seek error", err);
               return;
            }
            fs_ready = TRUE;         // everything Ok
            print("MMC/SD card inserted and mounted success.\r\nDon't forget umountsd before remove to prevent lost your data.\r\n");
            return;
         } else printError("Can't create Log file, check your SD.\r\nFS mount failed", err);   // else - show error
      } else printError("FatFs mount", err);
   } else    printError("MMC Connect", MMCD1.state);
}


and last function - append

Code: Select all

/**
 * @brief Appends specified line to the current log file
 */
void appendToLog(char *line) {
   UINT bytesWrited;
    if (!fs_ready) {
         print("appendToLog Error: No File system is mounted.\r\n");
         return;
   }
   size_t line_len = strlen(line);
   if (line_len == 0 || line_len > MAX_LOG_STRING_SIZE-2) {
         printError("appendToLog Error: String length zero or more then maximum-2 allowed = \r\n",line_len);
         return;
   }

      if (strncmp(errorlineReported, line, line_len) != 0) {      // current string to log and last string to log is not equal
         strncpy(errorlineReported, line, line_len);            // save for next compare
         strcat(errorlineReported, "\r\n");
         FRESULT err = f_write(&FDLogFile, line, line_len+2, &bytesWrited);   // write to file
         if (bytesWrited < line_len+2) {
            printError("write error or disk full", err);       // error or disk full
         }
         f_sync(&FDLogFile);                            // sync
      }
}


What i have in manual mode:
mmc_mount
FATfs Error "MMC Connect" 2
mmc_mount
MMC/SD card inserted and mounted success.
Don't forget umountsd before remove to prevent lost your data.
mmc_ls
----A 1980/01/01 00:00 190 rusefi.log
mmc_appendToLog 1235
mmc_ls
----A 1980/01/01 00:00 196 rusefi.log
mmc_umount
MMC/SD card removed.

1. Why mmc_mount working success from second trials. Other trials working fine.

But when i start periodically appendToLog - i receive unstable board running and panic.

2. I think problem with speed (SPI, MMC, so on). Please advice how to resolve.
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F4 Discovery MMC over SPI how to accelerate

Post by Giovanni »

Hi,

Hard to tell just looking at the code. Are you running with the debug options in chconf.h enabled? if so, is anything caught at runtime?

Giovanni
Kot_dnz
Posts: 10
Joined: Tue Jan 28, 2014 9:21 am

Re: STM32F4 Discovery MMC over SPI how to accelerate

Post by Kot_dnz »

What is correct sequence how to initialize MMC over SPI2 and receive maximum performance?

SPI2 connected to MMC: PB13 - SCK, PB14 - MISO, PB15 - MOSI, PD11 - CS, 3.3v

I try to show clear code - please specify where mistake or something lost:

Code: Select all

   
initSpiModule(&SPID2, GPIOB, 13, GPIOB, 14, GPIOB, 15, EFI_SPI2_AF);          // EFI_SPI2_AF = 5
static SPIConfig hs_spicfg = { NULL, GPIOD, 11, SPI_BaudRatePrescaler_8 };
static SPIConfig ls_spicfg = { NULL, GPIOD, 11, SPI_BaudRatePrescaler_256 };
static MMCConfig mmccfg = { &SPID2, &ls_spicfg, &hs_spicfg };
mmcObjectInit(&MMCD1);                  
mmcStart(&MMCD1, &mmccfg);               
mmcConnect(&MMCD1);


In URL http://jjmz.free.fr/?p=102 i found sample look like next:

Code: Select all

static SPIConfig hs_spicfg = { NULL, GPIOC, 4, 0 };
static SPIConfig ls_spicfg = { NULL, GPIOC, 4, SPI_CR1_BR_2 | SPI_CR1_BR_1 };
mmcObjectInit(&MMCD1, &SPID1, &ls_spicfg, &hs_spicfg, mmc_is_protected, mmc_is_inserted);
mmcStart(&MMCD1, NULL);
mmcConnect(&MMCD1);


may be in pins mistake... or they status...

Thank you.
Last edited by Kot_dnz on Mon Feb 03, 2014 2:29 pm, edited 1 time in total.
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F4 Discovery MMC over SPI how to accelerate

Post by Giovanni »

1) I don't too, unable to reproduce it here.
2) I am not aware of any queue for disk write, there is nothing that can oveflow. Are you writing from a single thread or multiple threads?

The MMC_SPI uses the SPI driver which uses DMA internally already, there is nothing to configure or optimize at that level.

Giovanni
Kot_dnz
Posts: 10
Joined: Tue Jan 28, 2014 9:21 am

Re: STM32F4 Discovery MMC over SPI how to accelerate

Post by Kot_dnz »

Giovanni wrote:Are you writing from a single thread or multiple threads?

Thank you for reply.
I receive log strings from one periodical thread.

Now I use MMC driver.
I found https://github.com/Torrentula/STM32F4-w ... lib/ff/src - running directly via SPI. (the same solution + with DMA (explained on russian) - http://rukodelie-ds.ru/forum/viewtopic.php?f=13&t=639 ) -> All this working directly via SPI.

May be SPI2 speed is to slow?
I never initialize it...
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F4 Discovery MMC over SPI how to accelerate

Post by Giovanni »

Hi,

I am lost. Care to explain what I am supposed to do with that code?

I can only suggest that you single step into the code and try to understand what is failing, not being to replicate the problem here I am unable to do that.

Giovanni
User avatar
russian
Posts: 368
Joined: Mon Oct 29, 2012 3:17 am
Has thanked: 16 times
Been thanked: 14 times

Re: STM32F4 Discovery MMC over SPI how to accelerate

Post by russian »

I am also involved with this code so I would try to clarify things a bit.

There are multiple issues here:
issue #1 - failure to mount SD on start-up
issue #2 - performance issue (?)

More on issue #1, failure to mount SD on start-up:

Code: Select all

main() {
halInit();
...
initSpiModules(); // this code configures the pins
//MMCmount();
addConsoleAction("mountsd", MMCmount);

and

Code: Select all

static void MMCmount(void) {
   if (fs_ready) {
      print("Error: Already mounted. \"umountsd\" first\r\n");
      return;
   }
   // start to initialize MMC/SD
   mmcObjectInit(&MMCD1);                  // Initializes an instance.
   mmcStart(&MMCD1, &mmccfg);               // Configures and activates the MMC peripheral.

   if (mmcConnect(&MMCD1) == CH_SUCCESS) {            // Performs the initialization procedure on the inserted card.
  ...
   ...


Everything works if we invoke 'MMCmount' via CLI - i.e. we manually type 'mountsd' when the application is running.
On the other hand, if we try to invoke same 'MMCmount' method right from the initialization code, the applications is hangling - and it seems like it is hanging on
'wait(MMCDriver *mmcp)' by send_hdr by send_command_R1 by mmcConnect invokation. Some kind of timing issue or order of execution issue, but I am failing to figure out what is wrong.

We are using 2.6.1, we have all DEBUG checks enabled - https://svn.code.sf.net/p/rusefi/code/t ... m/chconf.h

issue #2 - performance issue - should probably be discussed after we figure out the startup issue
User avatar
russian
Posts: 368
Joined: Mon Oct 29, 2012 3:17 am
Has thanked: 16 times
Been thanked: 14 times

Re: STM32F4 Discovery MMC over SPI how to accelerate

Post by russian »

PS: viewtopic.php?t=412 - but my card is transcend and I bet you Kot_dnz has some other card?
Same issue if SD card is removed from the socket.

The value in buf[0] received from spiReceive(mmcp->config->spip, 1, buf); is '0'

Code: Select all

static SPIConfig hs_spicfg = { NULL, SPI_SD_MODULE_PORT, SPI_SD_MODULE_PIN,
SPI_BaudRatePrescaler_8 };
static SPIConfig ls_spicfg = { NULL, SPI_SD_MODULE_PORT, SPI_SD_MODULE_PIN,
SPI_BaudRatePrescaler_256 };


PPS: 'Looks like it is a long wait.' - currently this is a while(true), should it be failing after some time, say 3 or 60 seconds and it's time to give up?
Kot_dnz
Posts: 10
Joined: Tue Jan 28, 2014 9:21 am

Re: STM32F4 Discovery MMC over SPI how to accelerate

Post by Kot_dnz »

Giovanni,

In one other source i found info that especially in STM32 SPI data sent via shifted register and at first time require clear it by send 0xff and only after there receive new data. If we receive data - viсe versa. Is this true?
Last edited by Kot_dnz on Tue Feb 04, 2014 4:36 pm, edited 1 time in total.
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F4 Discovery MMC over SPI how to accelerate

Post by Giovanni »

It could be a wiring problem or a pins programming problem, both are critical.

The CS must be a GPIO in output pushpull mode, and must be the same pin specified in SPIConfig.

I don't have connector to attach to the STM32F4-Discovery, I can test it on an Olimex STM32-P103, I will give it a try during the weekend but it always worked in the past. I followed this article as guideline for the current implementation: http://elm-chan.org/docs/mmc/mmc_e.html

Giovanni
Post Reply