0

I have a problem with stm32l4r5 (nucleo-l4r5zi) and reading SD cards. I am using fatfs from https://01001000.xyz/2020-08-09-Tutorial-STM32CubeIDE-SD-card/. SPI and CS pins pulled up, prescaler 256. I have 4 SD cards, but I can only communicate with 1. The mount, write and read procedure is OK (check print via UART). I can read the directory and file tree. The problem is that I can see files on the stm32, but not on the PC (SD card read by usb adapter) and vice versa. I've checked all the directories and drives and I can't see the files that were created on the PC. I don't have any idea about it now.

code for lising files:

FRESULT list_dir (const char \*path)
{
FRESULT res;
DIR dir;
FILINFO fno;
int nfile, ndir;

    res = f_opendir(&dir, path);                       /* Open the directory */
    if (res == FR_OK) {
        nfile = ndir = 0;
        for (;;) {
            res = f_readdir(&dir, &fno);                   /* Read a directory item */
            if (res != FR_OK || fno.fname[0] == 0) break;  /* Error or end of dir */
            if (fno.fattrib & AM_DIR) {            /* Directory */
                myprintf("   <DIR>   %s\r\n", fno.fname);
                ndir++;
            } else {                               /* File */
                myprintf("%10u %s\r\n", fno.fsize, fno.fname);
                nfile++;
            }
        }
        f_closedir(&dir);
        myprintf("%d dirs, %d files.\r\n\n", ndir, nfile);
    } else {
        myprintf("Failed to open \"%s\". (%u)\n", path, res);
    }
    return res;
}

code in program is the same like in the tutorial mentioned above.

How to check this files?

EDIT: All card use FAT32 file system, capacities are 1GB (3 of them) and 32GB, only 1GB works

EDIT2:

void myprintf(const char *fmt, ...) {
  static char buffer[256];
  va_list args;
  va_start(args, fmt);
  vsnprintf(buffer, sizeof(buffer), fmt, args);
  va_end(args);

  int len = strlen(buffer);
  HAL_UART_Transmit(&hlpuart1, (uint8_t*)buffer, len, -1);

}

FRESULT list_dir (const char *path)
{
    FRESULT res;
    DIR dir;
    FILINFO fno;
    int nfile, ndir;


    res = f_opendir(&dir, path);                       /* Open the directory */
    if (res == FR_OK) {
        nfile = ndir = 0;
        for (;;) {
            res = f_readdir(&dir, &fno);                   /* Read a directory item */
            if (res != FR_OK || fno.fname[0] == 0) break;  /* Error or end of dir */
            if (fno.fattrib & AM_DIR) {            /* Directory */
                myprintf("   <DIR>   %s\r\n", fno.fname);
                ndir++;
            } else {                               /* File */
                myprintf("%10u %s\r\n", fno.fsize, fno.fname);
                nfile++;
            }
        }
        f_closedir(&dir);
        myprintf("%d dirs, %d files.\r\n\n", ndir, nfile);
    } else {
        myprintf("Failed to open \"%s\". (%u)\n", path, res);
    }
    return res;
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_LPUART1_UART_Init();
  MX_USART3_UART_Init();
  MX_USB_OTG_FS_PCD_Init();
  MX_SPI1_Init();
  MX_FATFS_Init();
  /* USER CODE BEGIN 2 */

  myprintf("\r\n######### SD card write test #########\r\n\r\n");

    HAL_Delay(1000); /

    
    FATFS FatFs;    //Fatfs handle
    FIL fil;        //File handle
    FRESULT fres; //Result after operations

    char* fileName = "test06.txt";
    char textToSend[] = "Text come from 12545";

    uint32_t SZ_STR = 32;
    TCHAR str[SZ_STR];


    //Open the file system
    fres = f_mount(&FatFs, "", 1); //1=mount now
    uint_fast8_t status = 0;
    if (fres != FR_OK) {
        while (status == 0) {
            for (int j = 0; j < 5; ++j) {
                myprintf("f_mount error (%i).\r\n Try mount again %d/5\r\n", fres, j+1);
                HAL_Delay(1000);
                fres = f_mount(&FatFs, "", 1);
                if (fres == FR_OK) {
                    status = 1;
                    break;
                }
            }
            status = 1 ;
        }

            if (fres == FR_OK) {
                status = 1;
            }
        if (fres != FR_OK) {
            myprintf("f_mount FAILED");
            while(1);
        }
    }


    //list dir
    list_dir("2:");


    //Let's get some statistics from the SD card
    DWORD free_clusters, free_sectors, total_sectors;

    FATFS* getFreeFs;

    fres = f_getfree("", &free_clusters, &getFreeFs);
    if (fres != FR_OK) {
    myprintf("f_getfree error (%i)\r\n", fres);
    while(1);
    }

    //Formula comes from ChaN's documentation
    total_sectors = (getFreeFs->n_fatent - 2) * getFreeFs->csize;
    free_sectors = free_clusters * getFreeFs->csize;

    myprintf("\nSD card stats:\r\n%10lu KiB total drive space.\r\n%10lu KiB available.\r\n", total_sectors / 2, free_sectors / 2);

    /* check satus of file */
    FILINFO fno;
    fres = f_stat("example.txt", &fno);

    if (fres != FR_OK) {
        myprintf("f_status ERROR (%i)\r\n");
    } else {
    myprintf("\nStatus %s - DONE!\r\n", fno);
    myprintf("Attributes: %c%c%c%c%c\r\n",
                   (fno.fattrib & AM_DIR) ? 'D' : '-',
                   (fno.fattrib & AM_RDO) ? 'R' : '-',
                   (fno.fattrib & AM_HID) ? 'H' : '-',
                   (fno.fattrib & AM_SYS) ? 'S' : '-',
                   (fno.fattrib & AM_ARC) ? 'A' : '-');
    }


    // open file "test.txt"
    fres = f_open(&fil, "test.txt", FA_READ | FA_WRITE);
    if (fres != FR_OK) {
        myprintf("f_open 'test.txt' ERROR (%i)\r\n");
    } else {
    myprintf("\nOpen 'test.txt - DONE!\r\n");

        //Read 30 bytes from "test.txt" on the SD card
        BYTE readBuf[30];

        UINT readBr;
        char readCharBuf[20];
        fres = f_read(&fil, readCharBuf, 20, &readBr);
        if (fres == FR_OK) {
            myprintf("Read string from 'test.txt' contents: %s\r\n", readCharBuf);
        } else {
            myprintf("f_read error (%i)\r\n", fres);
        }

    }

    // close file
      f_close(&fil);

      /* open/create new file and write something */

    fres = f_open(&fil, (const TCHAR*)fileName, FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_APPEND);
       if(fres == FR_OK) {
        myprintf("Open %s for writing - DONE\r\n", fileName);
       } else {
        myprintf("f_open new file (%s) error (%i)\r\n\n", fileName, fres);
       }

    //Copy in a string
    BYTE writeBuf[30];

    strncpy((char*) writeBuf, textToSend, 20);
    UINT bytesWrote;
    fres = f_write(&fil, writeBuf, 20, &bytesWrote);

    if (fres == FR_OK) {
        myprintf("Wrote '%s' to '%s'\r\n", fileName, textToSend);
    } else {
        myprintf("f_write error (%i)\r\n");
    }

    f_close(&fil);

       // Open again test file
    myprintf("\nOpen file again\r\n");
        fres = f_open(&fil, (const TCHAR*)fileName, FA_READ | FA_WRITE);
        if (fres != FR_OK) {
            myprintf("f_open %s ERROR (%i)\r\n", fileName);
        } else {
        myprintf("\nOpen '%s' - DONE!\r\n", fileName);

            //Read 30 bytes from "test.txt" on the SD card
            BYTE readBuf[30];

            //We can either use f_read OR f_gets to get data out of files
            //f_gets is a wrapper on f_read that does some string formatting for us
            TCHAR *rres = f_gets((TCHAR*) readBuf, 30, &fil);
            if (rres != 0) {
                myprintf("Read string from '%s' contents: %s\r\n", fileName, rres);
            } else {
                myprintf("f_gets error (%i)\r\n", fres);
            }


        }

        // close file
          f_close(&fil);

    f_mount(NULL, "", 0);
    myprintf("File closed, card unmounted.");
Chey
  • 3
  • 2
  • Which capacities and which file systems do you use in detail? Please [edit] your question and add a table with these values, adding which one works with what system. – the busybee Jul 20 '23 at 11:41
  • Are you aware that SD cards use different communication protocols depending on their capacity? Research for SD/SDHC/SDXC, it might well be that your system does not support SDHC. – the busybee Jul 20 '23 at 11:52
  • You seem to have three different problems. 1) accessing more than one volume, 2) Files visible on target, but not PC 3) accessing large capacity cards. It would serve you well perhaps not to conflate these issues and concentrate on one at a time (and post separate questions on SO). .(2) seems unlikely somehow. Did you try running chkdsk? Did you try formatting with SD.org's SDCardFormatter? – Clifford Jul 20 '23 at 12:11
  • Your code fragment does not write to the card. What files are you expecting to see? When you have no idea where the problem is you should probably not be quite so specific in which code you choose to show. Does each volume have a separate and unique identifier? None of that is clear in your question. I strongly suggest using a debugger in preference to printing debug. With that you only see what you choose to show, and you are trying to fix code by writing _more_ code! What could possibly go wrong!? – Clifford Jul 20 '23 at 12:18
  • Correction sdcard.org: https://www.sdcard.org/downloads/formatter/ – Clifford Jul 20 '23 at 12:19
  • @thebusybee I now this differences beetwen protocols and capacity. I think problem is in 1) CUBE IDE configuration of SPI/FATFS 2) Hardware: pull-up pins with resistor? 3) I can not check other volumens? (if there are any) From what I understood, I save files from STm on one volume, after inserting the card into PC I can operate on another? I checked other paths ("0:" - defoult, "1:", "2:" -doesnt exist). I edited my first post and added the code – Chey Jul 21 '23 at 06:25
  • The difference is not on the SPI or hardware level, AFAIK. It is on the level of register meaning and content on the SD card. For example, the "unit" of addresses changes from "byte" to "block". -- As a guy working near hardware at times, _my_ next step would be to record the initial SPI sequences with a good DSO or logic analyzer and investigate that. Or, at a higher level, write an experimental program that accesses the SD cards directly on the SPI level. Yes, there is a high and steep learning curve... -- Anyway, perhaps some experienced user comes along to help you. – the busybee Jul 21 '23 at 06:38
  • @Clifford I updated first post. Yes, its looks like I'm adding more code to test the functionality. While debugging, everything works fine, except I can't read the files on the PC – Chey Jul 21 '23 at 07:14
  • 1
    You are mounting without specifying the logical drive name. That may be why you can only access one of your four cards, only the "default" volume will be selected. I may have misunderstood - perhaps you have four cards but one card slot? It is ambiguous. Another reason why you should trim this question of irrelevant but distracting information. – Clifford Jul 21 '23 at 13:19

0 Answers0