kiwih / cubeide-sd-card Goto Github PK
View Code? Open in Web Editor NEWCubeIDE/CubeMX compatible MMC/SD memory card FatFs driver
License: Other
CubeIDE/CubeMX compatible MMC/SD memory card FatFs driver
License: Other
Hello,
I have been trying to get functionality of using l_seek with F_size to get the end of a line since this version (and the HAL version for F0 chips in general) only supports up to R0.11 of FatFS which doesn't include the FA_APPEND flag.
No matter how much I write to the SD card, even when the files are verified off-system, f_size() function and indeed the fsize member of the file handler is always 0. This makes writing to the end of a file after file close extremely difficult. All other reading and writing functions work correctly. Indeed if I never close the file, I can write many lines without a problem, but for the use-case of having a removable and re-insertable SD card it is a huge problem.
Is this a reproducible error on your side?
Hello everyone,
I had to take over a project that used this driver and find the source of the low throughput obtained (only around 20kB/s when way more should have been possible).
Looking at the driver, I changed the lines for(UINT i=0; i<btx; i++) { xchg_spi(*(buff+i)); }
in function xmit_spi_multi
in file user_diskio_spi.c to HAL_SPI_Transmit(&SD_SPI_HANDLE, buff, btx, 100);
.
This greatly improved throughput (I am now around 800kB/s). I think there would be no difference if my SPI clock was way slower than my CPU clock, which is not my case but I don't see any advantage at the current way it is implemented.
Is there any reason why this is not done by default? I can do a pull request if this change would be accepted.
Have a good day!
At point 2 and 3 of the Adoption Guide section of the readme, the file FATFS/Target/user_spi.c
is mentioned. However, in my own testing (using an STM32L452), this file is called FATFS/Target/user_diskio.c
.
This might just be a thing with the STM32L4 CubeMX package generating the files differently, but I felt like it was worth mentioning.
Hi, I've followed the guide in the blog and ported your code to STM32L4. I had to enable the internal pull-ups of MISO, MOSI and CLK. Read works, but write doesn't. I've tried with several sd cards from different suppliers and sizes. The file write.txt never shows on the sd card, even if I create an empty one in advance I don't see the string written there. With 80MHz system clock I'm using SPI_BAUDRATEPRESCALER_256 for FCLK_SLOW and SPI_BAUDRATEPRESCALER_16 for FCLK_FAST.
This is the debug output of my program:
[I:control.c,200] SD Card test
[I:control.c,230] SD card stats:
119762 KiB total drive space.
119754 KiB available.
[I:control.c,238] I was able to open 'test.txt' for reading!
[I:control.c,246] Read string from 'test.txt' contents: Hey!
[I:control.c,271] Wrote 19 bytes to 'write.txt'!
I even added a FRES check for closing files and unmounting the filesystem. The functions always return FR_OK.
Any idea about what the problem could be? Anything else that should be changed when porting to STM32L4 (apart from #include "stm32l4xx_hal.h")?
Regards
The first time it's ok to mount the sd card and read/write files.
MX_SPI3_Init();
MX_FATFS_Init();
HAL_Delay(1000);
init_sdcard();
then I remove sd card and insert sd card, use the same code(above) to init sd card. It returns
f_mount error (1)
Is there any extra work to do?
I've been moving this eample over from bloated STM32 HAL SPI to LL. I was getting SPI sync issues, I now believe there may be an extraneous call to xchg_spi() within despiselect() function that HAL SPI may have been hiding. See:
/*-----------------------------------------------------------------------*/
/* Despiselect card and release SPI */
/*-----------------------------------------------------------------------*/
static
void despiselect (void)
{
CS_HIGH(); /* Set CS# high */
xchg_spi(0xFF); /* Dummy clock (force DO hi-z for multiple slave SPI) */ <<< THIS LINE CAUSED ISSUES
}
Hi!
great work!! I've seen very crappy code regarding SD SPI and STM32 but yours is very clean and tidy.
Just a suggestion, declare instead:
static uint32_t spiTimerTickStart;
static uint32_t spiTimerTickDelay;
They are not used outside user_diskio_spi.c file, so it is a good practice declare them static globals.
Hi!
How did you configure SCLK speeds, if I2SPR register is available only in I2S mode? I'm using STM32F103 but I checked on STM32F303RE user manual and it says: These bits should be configured when the I2S is disabled. They are used only when the I2S is in master mode. They are not used in SPI mode.
#define FCLK_SLOW() { SD_SPI_HANDLE.Instance->I2SPR = 128; } /* Set SCLK = slow, approx 280 KBits/s*/
#define FCLK_FAST() { SD_SPI_HANDLE.Instance->I2SPR = 8; } /* Set SCLK = fast, approx 4.5 MBits/s */
user_discio_spi.c, line 249:
resp = xchg_spi(0xFF); /* Receive data resp */
My SD card does not respond with 0x05 response immediately, only after one 0xFF. This function should wait with a timeout for NOT 0xFF and only then check the result.
Have you measured the throughput of reading file from SD card via spi?
Hi,
Following your blog, I have created a project for my F411 PCB board, where SPI5 is used for MCU to talk to SD card module.
I run my code and even cannot do the mounting, always getting error code 3.
So I did something like this: continuously trying f_mount
while(1) { fres = f_mount(&FatFs, "", 1); //1=mount now if (fres == FR_OK) { break; } sprintf(log_str, "f_mount error (%i)\r\n", fres); HAL_UART_Transmit(&huart2, (uint8_t *)log_str, strlen(log_str), 0xFFFF); }
After first error code 3, subsequently I got error code 1.
I used scope to monitor SPI5 SCK signal when running that infinite loop, it was flat.
However, if I just continuously call HAL_SPI_Transmit(&hspi5, tx_data, 4, 200);
, I can see SCK signal.
In my main.h, I do have #define SD_SPI_HANDLE hspi5
Can anyone shed some light on what I have missed?
Hi,
Following your blog, I have created a project for my F411 PCB board, where SPI5 is used for MCU to talk to SD card module.
I run my code and even cannot do the mounting, always getting error code 3.
So I did something like this: continuously trying f_mount
`
while(1) {
fres = f_mount(&FatFs, "", 1); //1=mount now
if (fres == FR_OK) {
break;
}
sprintf(log_str, "f_mount error (%i)\r\n", fres);
HAL_UART_Transmit(&huart2, (uint8_t *)log_str, strlen(log_str), 0xFFFF);
}
`
After first error code 3, subsequently I got error code 1.
I used scope to monitor SPI5 SCK signal when running that infinite loop, it was flat.
However, if I just continuously call HAL_SPI_Transmit(&hspi5, tx_data, 4, 200);
, I can see SCK signal.
In my main.h, I do have #define SD_SPI_HANDLE hspi5
Can anyone shed some light on what I have missed?
First of all, thanks for the well written how-to guide and blog post!
Thanks to your explanation and code I managed to read and write to a MicroSD card using a custom STM32F4 dev board ๐
However, it didn't work first-go and I had to spend a couple of hours to figure out what the issue was...
I have the microSD card directly connected to the SPI2 interface pins on a STM32F405RGT6, like so:
I altered and uploaded the code and it refused to work, it always gave me a f_mount error (3)
error...
I hooked up an SD card interface module (like the one you used in your blogpost) to the same SPI pins, and it started working!
After some probing I noticed that the SD card interface module has pullup resistors on all of the data lines.
After enabling the internal pullups of the SPI interface using the STM32CubeIDE configurator it suddenly started to work!
This was definitely a goof up on my part, but it would be nice to add a note on your blogpost or code to enable the internal pullups if someone is directly connecting the SD card pins to the STM32. Hopefully, it can save some other people some time so they don't have to go troubleshooting like I did ๐
I'm getting an error 128. I am following this tutorial https://01001000.xyz/2020-08-09-Tutorial-STM32CubeIDE-SD-card/ and was able to solve the issue with the f_open error 3 by fixing the user_diskio.c code by adding in the SPI returns using the user_diskio_spi.h. Now, that I am getting the size available on my SD card to print to putty using my UART. I'm getting a new error. f_open error (128).
I'm using SANSIDK ULTRA micro SD Card 32GB, which sandisk says they have SPI functionality here https://www.alliedelec.com/m/d/04db416b291011446889dbd6129e2644.pdf , see section 1.7 SPI Mode.
SPI1 SETTINGS AND SET UP
I manually changed these values to match my naming scheme
#define CS_HIGH() {HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_SET);} #define CS_LOW() {HAL_GPIO_WritePin(SPI1_CS_GPIO_Port, SPI1_CS_Pin, GPIO_PIN_RESET);}
I have changed the include in "user_diskio_spi.c" to use "stm32g0xx_hal.h" and managed to get it to run on an STM32g031F6, it fills quite a bit, but it works.
I then tried to make it run on an STM32g030J6, (should be about the same chip, just smaller) but for some reason, it just resets when it calls "f_mount".
I can trace it to "xchg_spi" in "user_diskio_spi.c". This function somehow fails and makes the chip reset. If I try to step into the function "HAL_SPI_TransmitReceive" in it, it just starts showing me assembly code.
Is there something I can try to test?
Hi,
I use STM32WL with LoRa and SD Card with your driver. My device use stop mode too. I feel confused when my device wake up from stop mode, then f_mount process fails. The error code that appears is always f_mount error (1).
I don't know what parameters need to be initialized again for SD Card system to work when wake up from stop mode. Maybe there is some configuration i'm missing, please help me.
Thank you
I use the f405rg, The CMD0 sometimes return 0xff and will get FR_NOT_READY.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.