Spark Logic

[libmaple] SDIO

stevestrong Sun Jun 18, 2017 5:20 pm

Hi all,

I finally managed to bring the SDIO files in an acceptable form to be published.

It works with 24MHz clock and 4bits wide bus, and tested only for the generic F407VET6 board.

I have committed 2 files to libmaple core directory, and 2 files to a new SDIO lib under STM32F4/libraries.

Usage:
– get the master branch from my repo
– get the SdFat lib from https://github.com/greiman/SdFat
– insert into line 164 of SdFatConfig:
#elif defined(__STM32F4__)
#define ENABLE_SDIO_CLASS 1

Replies

stevestrong Fri Aug 04, 2017 7:41 am

Good that is working in this way. Keep it.

victor_pv Mon Aug 07, 2017 7:16 pm

Steve, I have started working on the port to the F1.
So far I have a couple of questions for you:
1.- The function sdio_gpios_init() sets the pins for 4bit mode. Would not be helpful to allow the library to work in 1bit wide mode for anyone wanting to save a few GPIOs for something else, in which case the function should be able to set the pins for either 4bit or 1bit modes?
The function sdio_set_dbus_width() could call that one with a parameter to set the required number of pins to the right mode.

2.- There is a define for: #define SDIOCLK

stevestrong Tue Aug 08, 2017 7:51 am

Victor,
1. As far as I know:
– the SDIO 1 bit mode rd/wr performance is below the SPI performance.
– the number of pins needed for SDIO 1 bit mode is equal to number of pins needed by SPI.
– SDIO is available only for HIGH_LINE devices, where the number of pins is large enough.
Considering these, the SDIO 1 bit mode it only makes really sense if there is no free GPIO left and no free SPI port left on the chip, which I cannot really imagine.
However, you could implement it for the F1 line if you want, for the F4 family, where there are a lot of GPIOs available, I wouldn’t bother.

2. I agree, the clock should be best calculated from the current PLL and clock settings.
– But the time I developed that, I considered that for F4 I will anyway use only the 168MHz. Anyway, feel free to add the feature you want.

victor_pv Tue Aug 08, 2017 9:00 pm

[stevestrong – Tue Aug 08, 2017 7:51 am] –
Victor,
1. As far as I know:
– the SDIO 1 bit mode rd/wr performance is below the SPI performance.

There there is not much of a need to do it. I thought SDIO was more efficient than SPI mode even at 1bit. If not, a shared SPI with separate CS is a better way to save pins.

[stevestrong – Tue Aug 08, 2017 7:51 am] –
2. I agree, the clock should be best calculated from the current PLL and clock settings.
– But the time I developed that, I considered that for F4 I will anyway use only the 168MHz. Anyway, feel free to add the feature you want.

I’ll look at it, At the moment I’m using a define like you, but I still need to find time to test it, then ext will try to change that for the F1, and next hopefully send you a PR for the F4.

acronis Fri Aug 18, 2017 7:08 am

Hello stevestrong !

Can you tell time when you are planning to add support for I2C ?

stevestrong Fri Aug 18, 2017 7:16 am

Sorry, no, I cannot tell because currently I have no application for F4 which would involve I2C.

My priorities include the black F4 on-board SPI flash.
Then I intend to test the blue F4 board. I think that board includes an I2C flash chip, so this will bring your request forward.
As further step the Seed arch max is targeted.

Meanwhile, anyone is welcome to contribute.

Or, if you cannot wait, try the alternative cores: generic, HAL, stm32duino.

acronis Fri Aug 18, 2017 7:40 am

I really like Your library, You already realized that I am using in my projects.
Required only support I2C.
I really like the black Board STM32F407VET6.
I’ll wait for your implementation !
All the best to You !

michael_l Wed Sep 12, 2018 7:23 pm

Trying SDIO examples with steve’s latest core (master branch). But I’m getting always this error. Am I perhaps missing something ? Should ‘flags’ parameter be set to some default value so it compiles ?

C:\Users\michael\Documents\Arduino\hardware\Arduino_STM32_Steve\STM32F4\libraries\SdFat\src\SpiDriver\SdSpiSTM32.cpp: In member function 'uint8_t SdSpiAltDriver::receive(uint8_t*, size_t)':

C:\Users\michael\Documents\Arduino\hardware\Arduino_STM32_Steve\STM32F4\libraries\SdFat\src\SpiDriver\SdSpiSTM32.cpp:89:38: error: call of overloaded 'dmaTransfer(int, uint8_t*&, size_t&)' is ambiguous

return m_spi->dmaTransfer(0, buf, n);

^

C:\Users\michael\Documents\Arduino\hardware\Arduino_STM32_Steve\STM32F4\libraries\SdFat\src\SpiDriver\SdSpiSTM32.cpp:89:38: note: candidates are:

In file included from C:\Users\michael\Documents\Arduino\hardware\Arduino_STM32_Steve\STM32F4\libraries\SdFat\src\SpiDriver\SdSpiDriver.h:32:0,

from C:\Users\michael\Documents\Arduino\hardware\Arduino_STM32_Steve\STM32F4\libraries\SdFat\src\SpiDriver\SdSpiSTM32.cpp:26:

C:\Users\michael\Documents\Arduino\hardware\Arduino_STM32_Steve\STM32F4\libraries\SPI\src/SPI.h:303:10: note: void SPIClass::dmaTransfer(const void*, void*, uint16, uint16)

void dmaTransfer(const void * transmitBuf, void * receiveBuf, uint16 length, uint16 flags = 0);

^

C:\Users\michael\Documents\Arduino\hardware\Arduino_STM32_Steve\STM32F4\libraries\SPI\src/SPI.h:304:10: note: void SPIClass::dmaTransfer(uint16_t, void*, uint16, uint16)

void dmaTransfer(const uint16_t tx_data, void * receiveBuf, uint16 length, uint16 flags = 0);

^

C:\Users\michael\Documents\Arduino\hardware\Arduino_STM32_Steve\STM32F4\libraries\SdFat\src\SpiDriver\SdSpiSTM32.cpp:94:1: warning: control reaches end of non-void function [-Wreturn-type]

}

^

Using library SDIO in folder: C:\Users\michael\Documents\Arduino\hardware\Arduino_STM32_Steve\STM32F4\libraries\SDIO (legacy)
Using library SdFat at version 1.0.5 in folder: C:\Users\michael\Documents\Arduino\hardware\Arduino_STM32_Steve\STM32F4\libraries\SdFat
Using library SPI at version 1.0 in folder: C:\Users\michael\Documents\Arduino\hardware\Arduino_STM32_Steve\STM32F4\libraries\SPI
exit status 1
Error compiling for board Generic STM32F407V mini series.

madias Wed Sep 12, 2018 8:55 pm

I think Steve is using a modified (better: more actual) branch of the SDfat library, you could install this one:
https://github.com/stevstrong/SdFat
So here you can see the DMA changes:
https://github.com/stevstrong/SdFat/blo … iSTM32.cpp
Beware if your SDFat library is global that it might not working with other cores (I’m always try to include them not global but in /hardware/<branch>/<subfolder> -> libraries for each core) This is a known Arduino problem about the priority of libraries…
Steves branch must be used with caution (In his F1 maple mini is broken, caused by a new ADC structure).

michael_l Wed Sep 12, 2018 9:09 pm

[madias – Wed Sep 12, 2018 8:55 pm] –
I think Steve is using a modified (better: more actual) branch of the SDfat library, you could install this one:
https://github.com/stevstrong/SdFat
So here you can see the DMA changes:
https://github.com/stevstrong/SdFat/blo … iSTM32.cpp
Beware if your SDFat library is global that it might not working with other cores (I’m always try to include them not global but in /hardware/<branch>/<subfolder> -> libraries for each core)
Steves branch must be used with caution (In his F1 maple mini is broken, caused by a new ADC structure).

Thanks ! I tried that and it works. I was under impression that SdFat under Steve’s F4 repo would be working.

stevestrong Wed Sep 12, 2018 9:16 pm

As Matthias said, use the SdFat lib and SPI lib from my repo, i updated them lately exactly because of this issue.
Which was caused because i added versions of SPI dma function transfer().

flyboy74 Thu Sep 13, 2018 3:51 am

[stevestrong – Tue Aug 08, 2017 7:51 am] –
Victor,
1. As far as I know:
– the SDIO 1 bit mode rd/wr performance is below the SPI performance.
– the number of pins needed for SDIO 1 bit mode is equal to number of pins needed by SPI.
– SDIO is available only for HIGH_LINE devices, where the number of pins is large enough.
Considering these, the SDIO 1 bit mode it only makes really sense if there is no free GPIO left and no free SPI port left on the chip, which I cannot really imagine.
However, you could implement it for the F1 line if you want, for the F4 family, where there are a lot of GPIOs available, I wouldn’t bother.

2. I agree, the clock should be best calculated from the current PLL and clock settings.
– But the time I developed that, I considered that for F4 I will anyway use only the 168MHz. Anyway, feel free to add the feature you want.

Ok as always I am a noob but I will still post what my understating is and the experience that I have and anyone can correct me if I am wrong as it is how I learn.

I have used SD in SPI, 1_line and 4_line a reasonable bit in Micro-Python and a bit on STM32F4 with Cube MX, HAL and FATFS.

SPI has the advantage that if your going to need SPI for other things then you will need the MOSI, MISO and CLK lines anyway so it will just use an extra CS pin. But in my experience it is limited to using the SD card at a max of 25Mhz as the SPI is on the APB1 clock and can’t run in High Speed mode of 50Mhz.

SD 1_line uses I less line that SPI as it doesn’t have a CS pin but can be used in high speed mode of 50Mhz as SDIO is on the APB2 so if you don’t need the SPi bus for anything else it saves I line and is possible to have twice the transfer rate as SPI.

SD 4_Line uses 2 more lines than SPI but is 4 bits wide and can also be used in high speed mode so can get transfers at 8 times the speed as SPI

A quick google I found this

sd.JPG
sd.JPG (54.87 KiB) Viewed 273 times

stevestrong Thu Sep 13, 2018 6:39 am

SPI_1 runs with 42mhz and is usable.

Sdio cannot run with 42mhz due to a hw issue, chech the errata sheet. At least in 4bit mode, i dont know in 1 bit mode.

flyboy74 Thu Sep 13, 2018 8:32 am

[stevestrong – Thu Sep 13, 2018 6:39 am] –
SPI_1 runs with 42mhz and is usable.

Sdio cannot run with 42mhz due to a hw issue, chech the errata sheet. At least in 4bit mode, i dont know in 1 bit mode.

Thanks Stevestrong.

I did just google the doc and have a bit of a read but didn’t really understand what it was saying so I don’t understand the problem.

The doc seems to contradict the reference manual too which quotes this
SDIO_CK is the clock to the card: one bit is transferred on both command and data lines
with each clock cycle.
The SDIO uses two clock signals:
• SDIO adapter clock SDIOCLK up to 50 MHz (48 MHz when in use with USB)
• APB2 bus clock (PCLK2)
PCLK2 and SDIO_CK clock frequencies must respect the following condition:
Frequenc(PCLK2) ≥ 3 ⁄ 8 × Frequency(SDIO_CK)

stevestrong Thu Sep 13, 2018 8:36 am

Which doc?
Where is the contradiction?
[flyboy74 – Thu Sep 13, 2018 8:32 am] –
I did just google the doc and have a bit of a read but didn’t really understand what it was saying so I don’t understand the problem.

Well, in this case I would not dig deeper. 8-)

flyboy74 Thu Sep 13, 2018 9:07 am

[stevestrong – Thu Sep 13, 2018 8:36 am] –
Which doc?
Where is the contradiction?
[flyboy74 – Thu Sep 13, 2018 8:32 am] –
I did just google the doc and have a bit of a read but didn’t really understand what it was saying so I don’t understand the problem.

Well, in this case I would not dig deeper. 8-)

Then I will never understand. I like learning new things.

Is this the problem you refer too??
SDIO clock divider BYPASS
mode may not work properly
If I am understanding this properly this means that you can’t bypass the divider so that means if you don’t bypass(i.e BYPASS bit is equal to “0”) and use the min value for the divider then max speed of SDIO will be 42MHz

Is this the HW problem you talk about???

flyboy74 Thu Sep 13, 2018 9:20 am

Will it work if you setup SDI clock control register (SDIO_CLKCR) like this??
Bit 10 BYPASS = 0
Bits 7:0 CLKDIV = 0

where SDIO_CK frequency = SDIOCLK / [CLKDIV + 2].
This gives 82MHz / [0 +2] = 42MHz

With clocks setup like this??

clocks.JPG
clocks.JPG (49.74 KiB) Viewed 250 times

stevestrong Thu Sep 13, 2018 9:21 am

I am referring to:
2.11.6 No underrun detection with wrong data transmission
Description
In case there is an ongoing data transfer from the SDIO host to the SD card and the hardware flow control is disabled (bit 14 of the SDIO_CLKCR is not set), if an underrun condition occurs, the controller may transmit a corrupted data block (with wrong data word) without detecting the underrun condition when the clock frequencies have the following relationship:
[3 x period(PCLK2) + 3 x period(SDIOCLK)] >= (32 / (BusWidth)) x period(SDIO_CK)
Workaround
Avoid the above-mentioned clock frequency relationship, by:
• Incrementing the APB frequency
• or decreasing the transfer bandwidth
• or reducing SDIO_CK frequency
As workaround, there is only the last option feasible, if we want to keep USB (48Mhz), and no overclocking. The next available frequency lower than 48MHz is the half of it, 24MHz.

flyboy74 Thu Sep 13, 2018 9:32 am

OK thanks for the explanation. I am now a little smarter than 1 hr ago.

I do see 2 options
1. SDIO 1_line running at 42Mhz
2. SDIO 4_line running at 24MHz

If both of these options work then SDIOI 1_line will be same speed at SPI and SDIO 4_line will be double the speed of SPI

stevestrong Thu Sep 13, 2018 9:39 am

This is why sdio 1 line mode doesn’t make too much sense.

If there is an SD slot on board connected to SDIO lines, use that in SDIO_4 mode.
Otherwise use SPI 1 (@42MHz) for max performance.

Sign in to reply