cancel
Showing results for 
Search instead for 
Did you mean: 

Why is the STM32 FATFs example working on Disco413ZH and not on Nucleo413ZH

magene
Senior II

I'm trying to port the STM provided STM32 Cube MX -> STM32F413H-Discovery -> FatFS_uSD example from the Disco413 board to the Nucleo413ZH board. I've got the example working fine on the Disco413 board using the VisualGDB IDE. I can run it multiple times opening new files, appending to old files and so forth. I'm trying to get the exact same code running on a Nucleo413ZH board and it will only run correctly once. If I try to run the code a second time it doesn't return FR_OK at line 21 in the f_open subroutine in ff.c. I haven't been able to figure out exactly what combination of reset, power down/up, moving from running on the Nucleo to running on the Disco and back or other step makes the code work again on the Nucleo but it does occasionally.

I can single step my way into the details but haven't figured out where the problem is and I'm really hoping that someone may be able to just point me at what else I need to change in the STM Disco code to get it working on the Nucleo.

If anyone is interested in the details, here's what I've figured out. Here's line 21 where it hangs in ff.c.

FRESULT f_open (
	FIL* fp,			/* Pointer to the blank file object */
	const TCHAR* path,	/* Pointer to the file name */
	BYTE mode			/* Access mode and file open mode flags */
)
{
	FRESULT res;
	DIR dj;
	FATFS *fs;
#if !_FS_READONLY
	DWORD dw, cl, bcs, clst, sc;
	FSIZE_t ofs;
#endif
	DEF_NAMBUF
 
 
	if (!fp) return FR_INVALID_OBJECT;
 
	/* Get logical drive */
	mode &= _FS_READONLY ? FA_READ : FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_CREATE_NEW | FA_OPEN_ALWAYS | FA_OPEN_APPEND | FA_SEEKEND;
	res = find_volume(&path, &fs, mode);
	if (res == FR_OK) {

If I single step into find_volume, the code can't get past the while loop in one of the SDMMC_GetCmdRespX subroutines but I haven't been able to find a repeatable problem.

static uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint32_t Timeout)
{
  uint32_t response_r1;
  uint32_t sta_reg;
  
  /* 8 is the number of required instructions cycles for the below loop statement.
  The Timeout is expressed in ms */
  register uint32_t count = Timeout * (SystemCoreClock / 8U /1000U);
  
  do
  {
    if (count-- == 0U)
    {
      return SDMMC_ERROR_TIMEOUT;
    }
    sta_reg = SDIOx->STA;
  }while(((sta_reg & (SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) == 0U) ||
         ((sta_reg & SDIO_FLAG_CMDACT) != 0U ));
    

I'm using a QuikChip CN0023 micoSD adapter ( http://www.chipquik.com/datasheets/CN0023.pdf ) on the Nucleo and have it wired to the same pins on the Nucleo as the built in SD card on the Disco uses. The fact that it runs once and I can check the file exists with the right content on my PC suggests that it isn't a wiring issue. I'm still using the stm32F413h_discovery.c and _discovery_sd.c files in my project because I haven't found a Nucleo413ZH equivalent but I can't see anything board specific in there. Here's the virtually untouched example code form STM and any suggestions will be greatly appreciated.

#include "main.h"
 
/* Private variables ---------------------------------------------------------*/
FATFS SDFatFs;  /* File system object for SD card logical drive */
FIL MyFile;     /* File object */
char SDPath[4]; /* SD card logical drive path */
static uint8_t buffer[_MAX_SS]; /* a work buffer for the f_mkfs() */
 
/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);
static void Error_Handler(void);
 
int main(void)
{
  FRESULT res;                                          /* FatFs function common result code */
  uint32_t byteswritten, bytesread;                     /* File write/read counts */
  uint8_t wtext[] = "Test file on Nucleo413ZH"; /* File write buffer */
  uint8_t rtext[100];                                   /* File read buffer */
  
  HAL_Init();
 
  /* Configure the system clock to 100 MHz */
  SystemClock_Config();
  
  /* Configure LED3 and LED4 */
//  BSP_LED_Init(LED3);
//  BSP_LED_Init(LED4);
  
  /*##-1- Link the micro SD disk I/O driver ##################################*/
  if(FATFS_LinkDriver(&SD_Driver, SDPath) == 0)
  {
    /*##-2- Register the file system object to the FatFs module ##############*/
    if(f_mount(&SDFatFs, (TCHAR const*)SDPath, 0) != FR_OK)
    {
      /* FatFs Initialization Error */
      Error_Handler();
    }
    else
    {
      /*##-3- Create a FAT file system (format) on the logical drive #########*/
      /* WARNING: Formatting the uSD card will delete all content on the device */
//      if(f_mkfs((TCHAR const*)SDPath, FM_ANY, 0, buffer, sizeof(buffer)) != FR_OK)
//      {
//        /* FatFs Format Error */
//        Error_Handler();
//      }
//      else
      {       
        /*##-4- Create and Open a new text file object with write access #####*/
//	      if (f_open(&MyFile, "File12.TXT", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
	      if(f_open(&MyFile, "F72.TXT", FA_OPEN_APPEND | FA_WRITE) != FR_OK)
		      {
          /* 'STM32.TXT' file Open for write Error */
          Error_Handler();
        }
        else
        {
          /*##-5- Write data to the text file ################################*/
          res = f_write(&MyFile, wtext, sizeof(wtext), (void *)&byteswritten);
 
          /*##-6- Close the open text file #################################*/
          if (f_close(&MyFile) != FR_OK )
          {
            Error_Handler();
          }
          
          if((byteswritten == 0) || (res != FR_OK))
          {
            /* 'STM32.TXT' file Write or EOF Error */
            Error_Handler();
          }
          else
          {      
            /*##-7- Open the text file object with read access ###############*/
            if(f_open(&MyFile, "F72.TXT", FA_READ) != FR_OK)
            {
              /* 'STM32.TXT' file Open for read Error */
              Error_Handler();
            }
            else
            {
              /*##-8- Read data from the text file ###########################*/
              res = f_read(&MyFile, rtext, sizeof(rtext), (UINT*)&bytesread);
              
              if((bytesread == 0) || (res != FR_OK))
              {
                /* 'STM32.TXT' file Read or EOF Error */
                Error_Handler();
              }
              else
              {
                /*##-9- Close the open text file #############################*/
                f_close(&MyFile);
                
                /*##-10- Compare read data with the expected data ############*/
                if((bytesread != byteswritten))
                {                
                  /* Read data is different from the expected data */
                  Error_Handler();
                }
                else
                {
                  /* Success of the demo: no error occurrence */
                  //BSP_LED_On(LED3);
                }
              }
            }
          }
        }
      }
    }
  }
  
  /*##-11- Unlink the RAM disk I/O driver ####################################*/
  FATFS_UnLinkDriver(SDPath);
 
  
  /* Infinite loop */
  while (1)
  {
  }
}

3 REPLIES 3
JChrist
Associate III

How long does it hang for? This line in sd_diskio.c should dictate the timeout:

#define SD_TIMEOUT 30 * 1000

What version of firmware are you using? 1.24.1, 1.25.0, other?

I don't really have an answer for you just similar problems myself.

Jacob

Clive1 (HNL)
Senior II

The adapter lacks pull-up resistors, at least pictures I've seen.

Make sure you have pull-up enabled on DATA/CLK lines.

Check you are using the right pin for the CARD DETECT SWITCH, or disable that functionality.

I'd use the ViewTool / WaveShare adapters

https://www.waveshare.com/micro-sd-storage-board.htm

magene
Senior II

@Community member​ You're right, my adapter doesn't have pull-up resistors and the schematic for the Discovery board does have pull-ups on the SD lines. I caught that at the beginning and made sure the pull-up is selected in the pin configuration. And I've confirmed that my code is getting past the part where it checks to make sure the card is detected. I've just recently put a logic analyzer on the signals and there's a funny delay in the middle of the transfer. I haven't had had a chance to pursue that issue yet but will get back to it soon. Regardless, I'm going to order a couple of the Waveshare boards.

As always, thanks for your help.