cancel
Showing results for 
Search instead for 
Did you mean: 

SDIO and SD fat access example?

natblist
Associate
Posted on February 09, 2012 at 01:06

Hi Chaps,

Going slowly mad trying to get Chan Fat working with the sdio libs on a stm32f4.

I'm using the most recent (1.0.0) library for the F4, and the low level access demo within that library builds and (at least appears to ) work OK. 

I've spent many, many hours attempting to patch in 0.9 version of fatfs from chan (thks chan, you're a hero) - but I can't get it to work.

If possible, I'd really really appreciate a demo project/source (or direction to - though I've scoured the web and can't find anything that works!)

I'll post separately about the current problems I'm having with the my current build, but a working example would sort it.

Many thanks,

nat.

#hse-sdio-stm32 #stm32-fat-chanfat-fatfs-sdio #sdcard-stm32f4-sdio-fatfs #sdcard-stm32f4-sdio-fatfs
84 REPLIES 84
Posted on November 20, 2013 at 16:19

As discussed earlier in the thread the use of small block sizes is both detrimental to the SD Card and FatFs operation.

I like 32KB, its a good mix of sectors, cluster, and block alignment. The flash device likely blocks at 128KB. Use an SDFormatter application to format cards (the factory does this), the classic DOS/Windows tools don't pay attention to the alignment needs of the flash.

Below 512 bytes it gets worse, everything has to be deblocked, and is wasteful of IO operations. Caching can help, better buffering at the application level helps more.

Assuming Q tap of the PLL is at 48 MHz

#define SDIO_TRANSFER_CLK_DIV            ((uint8_t)0x0) // 24 MHz
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
hitsumen
Associate II
Posted on November 20, 2013 at 17:33

clive1 I used the system_stm32f4xx.c from your example of FATFS-DBG which you posted here.

I will be able to scope the clock on friday. 

#define PLL_M      8

#define PLL_N      240

#define PLL_P      2

#define PLL_Q      5

#define PLLI2S_N   192

#define PLLI2S_R   5

I did like you said, formated my card with SDFormatter, then try to write 32768 * 32:

f_open(&file, ''test.txt'', FA_WRITE | FA_CREATE_ALWAYS);

for(i = 0; i < 32; i++)

f_write(&file, buff, 32768, &bw);

f_close(&file);

It writes with speed ~1 MB/s much better!

God bless you!

//Nikolaj

Posted on November 20, 2013 at 18:12

Ok, so my primary platform is an F2 hence the 120 MHz set up.

The STM32F4-DIS-BB version runs at 168 MHz

/************************* PLL Parameters *************************************/
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M 8
#define PLL_N 336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P 2
/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
#define PLL_Q 7
/* PLLI2S_VCO = (HSE_VALUE Or HSI_VALUE / PLL_M) * PLLI2S_N
I2SCLK = PLLI2S_VCO / PLLI2S_R */
#define PLLI2S_N 192
#define PLLI2S_R 5
/******************************************************************************/

This most recent release of that was here

https://drive.google.com/file/d/0B7OY5pub_GfIY01DaHY4OVp4NUk/edit?usp=sharing

And I have another one for the STM32F401C-DISCO (84 MHz Value Line)

https://drive.google.com/file/d/0B7OY5pub_GfIU0VFWWs2dmxKOFE/edit?usp=sharing

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
hitsumen
Associate II
Posted on November 20, 2013 at 18:54

clive1,

 

Again, i got some wrong stuff, when I am writing 32768, only 512 is good data other 32256 bytes are 0xFF; Maybe it is the reason why it writes so fast.... Not possible to exceed 512 bytes?

[EDIT]

 

I have mixed my code with your code(took files like diskio.c, diskio.h, some others).

Now finally it looks like something is working.

Speed in 1-bit mode is something like ~2.3MB/s with both cards:

Kingston class 4 8GB ~2.3MB/s.

Some no name card 2GB (took from Nokia 6300i phone) not SDHC ~2.3MB/s.

In test I was writing 8MB file.

To others:

Added some code to diskio.c function disk_initialize(..)

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure); 

Thank you clive1,

//Nikolaj
hariprasad
Associate III
Posted on June 05, 2015 at 19:33

Hi Clive,,

Thanks for your code... what was the throughput you obtained form a write and read ?

I used a similar code to your's but gets only 500kB/s only ...

Posted on June 05, 2015 at 20:30

Thanks for your code... what was the throughput you obtained form a write and read ?

 

I used a similar code to your's but gets only 500kB/s only ...

I think I've posted quite a few benchmarks throughout the thread, try the 1 and 4-bit mode numbers in the post just up from this. Write speeds are very dependent on the card being used, and the size of the write operations (at the card).

Yes, 500 KBps seems rather sucktacular, make sure you're using DMA, and 4-bit mode, and the speed you've configured for the interface.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
roy23
Associate II
Posted on June 08, 2015 at 14:15

Hi,

trying to integrate file system + sdio to my device.

sdio + fs works well reading and writing when I am canceling the call to turn on HSE.

RCC_HSEConfig( RCC_HSE_ON ); but then I loose all other peripherals that were working to this point.

when I turn on the HSE. all peripheral work good but the sdio fails to initialize. any direction what can be the origin of this problem ?

hariprasad
Associate III
Posted on June 08, 2015 at 15:07

Hi,

I not sure ,, but check the PLL_P_CONSTANT or something similar to PLL_P value should be 4<=value<=15,

 

 

This divides the core clock by the value PLL_P and gives to USB and SDIO peripherals,, if this clock exceeds 48MHZ some issue might happen

 

 

hariprasad
Associate III
Posted on June 08, 2015 at 15:11

HI Clive ,

When I further debugged into code I can see a function

DRESULT TM_FATFS_SD_SDIO_disk_write(const BYTE *buff, DWORD sector, UINT count) {

 

    SD_Error Status = SD_OK;

 

 

    if (!TM_FATFS_SDIO_WriteEnabled()) {

 

        return RES_WRPRT;

 

    }

 

 

    if (SD_Detect() != SD_PRESENT) {

 

        return RES_NOTRDY;

 

    }

 

 

    if ((DWORD)buff & 3) {

 

        DRESULT res = RES_OK;

 

        DWORD scratch[BLOCK_SIZE / 4];

 

 

        while (count--) {

 

            memcpy(scratch, buff, BLOCK_SIZE);

 

            res = TM_FATFS_SD_SDIO_disk_write((void *)scratch, sector++, 1);

 

 

            if (res != RES_OK) {

 

                break;

 

            }

 

 

            buff += BLOCK_SIZE;

 

        }

 

 

        return(res);

 

    }

 

 

    Status = SD_WriteMultiBlocks((uint8_t *)buff, sector << 9, BLOCK_SIZE, count); // 4GB Compliant

 

 

    if (Status == SD_OK) {

 

        SDTransferState State;

 

 

        Status = SD_WaitWriteOperation(); // Check if the Transfer is finished

 

 

        while ((State = SD_GetStatus()) == SD_TRANSFER_BUSY); // BUSY, OK (DONE), ERROR (FAIL)

 

 

        if ((State == SD_TRANSFER_ERROR) || (Status != SD_OK)) {

 

            return RES_ERROR;

 

        } else {

 

            return RES_OK;

 

        }

 

    } else {

 

        return RES_ERROR;

 

    }

 

}

 

 

So I just put a count so that i can see in each write howmany times is this function being called..

I could see that whenever the throughput is low, this function was called more than 1 time which created the low performance..... and when I got minimum time for a write this function was called only one single time..

Do you have any idea regarding why this function was being called more than 1 time ,,,sometimes... ?

 

Posted on June 08, 2015 at 15:14

I really have no idea about your system, the board, configuration, etc.

The SD Card requires the PLL be running to function. You'd need to review the system_stm32f4xx.c with respect to your chip/board.

If the problem relates to HSE, perhaps explain what crystal you're using on your board, and confirm it's actually starting/present. Then look at the PLL settings in that context, and confirm it's locking, and that it's selected by the system as the processor clock.

SystemInit() typically configures the clocks, and gets called before main() in the CMSIS model.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..