Spark Logic

SPI on F4

ag123 Fri May 05, 2017 3:12 pm

out of sheer curiosity i took a peek at the SPI section in RM0009 reference manual for F4
http://www.st.com/content/ccc/resource/ … 031020.pdf
vs RM0008 reference manual for F1*
http://www.st.com/content/ccc/resource/ … 171190.pdf

there a a lot of parts that looked literally ‘identical’, how i hoped pdf viewers can do a ‘diff’ and just tell me what are the differences :D

i noted the following as 1 of the difference:
STM32F1 RM0008 p710 25.3.3 Configuring the SPI in master mode
25.3.3 Configuring the SPI in master mode
Procedure
1. Select the BR[2:0] bits to define the serial clock baud rate (see SPI_CR1 register).
2. Select the CPOL and CPHA bits to define one of the four relationships between the data transfer and the serial clock (see Figure 239).
3. Set the DFF bit to define 8- or 16-bit data frame format
4. Configure the LSBFIRST bit in the SPI_CR1 register to define the frame format.
5. If the NSS pin is required in input mode, in hardware mode, connect the NSS pin to a high-level signal during the complete byte transmit sequence. In NSS software mode, set the SSM and SSI bits in the SPI_CR1 register. If the NSS pin is required in output
mode, the SSOE bit only should be set.
6. The MSTR and SPE bits must be set (they remain set only if the NSS pin is connected
to a high-level signal). In this configuration the MOSI pin is a data output and the MISO pin is a data input.

STM32F1 RM0009 p887 28.3.3. Configuring the SPI in master mode

28.3.3. Configuring the SPI in master mode
In the master configuration, the serial clock is generated on the SCK pin.
Procedure
1. Select the BR[2:0] bits to define the serial clock baud rate (see SPI_CR1 register).
2. Select the CPOL and CPHA bits to define one of the four relationships between the data transfer and the serial clock (see Figure 248). This step is not required when the TI mode is selected.
3. Set the DFF bit to define 8- or 16-bit data frame format
4. Configure the LSBFIRST bit in the SPI_CR1 register to define the frame format. This step is not required when the TI mode is selected.
5. If the NSS pin is required in input mode, in hardware mode, connect the NSS pin to a high-level signal during the complete byte transmit sequence. In NSS software mode, set the SSM and SSI bits in the SPI_CR1 register. If the NSS pin is required in output mode, the SSOE bit only should be set. This step is not required when the TI mode is selected.
6. Set the FRF bit in SPI_CR2 to select the TI protocol for serial communications.
7. The MSTR and SPE bits must be set (they remain set only if the NSS pin is connected to a high-level signal).
configuration the MOSI pin is a data output and the MISO pin is a data input.

while this is unlikely to be the only difference what seem rather distinct is this addition of the ‘TI mode’
a timing diagram is given on p887 RM0009 SPI TI protocol in master mode
apparently the ‘TI mode’ seemed to have things like ‘triggering edge’ and ‘sampling edge’ and it seem to start with single NSS high pulse sequence
the other ‘strange’ thing about this P887 RM0009 SPI TI protocol timing diagram is it seem to label MOSI as ‘input’ while MISO as ‘output’ this doesn’t seem to match the notions of how we’d usually do SPI since stm32 is the ‘master’ (seemed more like an error in the diagram)
my thoughts are in step (6) above, we’d need to *switch off* TI mode to get the ‘regular’ SPI we’d expect
in particular if we do use the NSS pin as a custom /CS pin for the SPI devices (i always do that so as not to ‘waste’) pins :lol:
but then the default for SPI_CR2 FRF at reset seem to be 0 motorola mode (rather than 1 TI mode)

just 2 cents

Replies

ag123 Fri May 05, 2017 3:37 pm

nope, this doesn’t seem like a meaningful difference since TI mode is off by default

stm32 also use the same boundary addresses and register addresses for SPI1 and SPI2, SPI3
0x4001 3000 – 0x4001 33FF SPI1
0x4000 3800 – 0x4000 3BFF SPI2/I2S
0x4000 3C00 – 0x4000 3FFF SPI3 / I2S3

stevestrong Fri May 05, 2017 3:38 pm

ag123 wrote:the default for SPI_CR2 FRF at reset seem to be 0 motorola mode (rather than 1 TI mode)

ag123 Fri May 05, 2017 3:44 pm

i’m starting to suspect if it may be something related to the AHB clocks / prescalers or APB clocks / prescalers
as after all the F4 runs at 168 mhz while an F1 runs at 72 mhz, lots of things to hunt down to figure out differences esp if things don’t work

the TI mode it seemed is that additional use of the NSS pin which based on the RM is default off and motorola mode is used instead

another thing which we may need to check may be to see if a particular peripheral bus is clocked.

found a web that seemed useful on the topic of clocks
https://stm32f4-discovery.net/2015/01/p … x-devices/
settings seem to match that used on steves F4 black branch, the PLL multipliers seemed similar
https://github.com/stevstrong/Arduino_S … cF4.c#L431
void SetupClock168MHz() {
...
// save bus clock values
rcc_dev_clk_speed_table[RCC_AHB1] = (SystemCoreClock/1);
rcc_dev_clk_speed_table[RCC_APB2] = (SystemCoreClock/2);
rcc_dev_clk_speed_table[RCC_APB1] = (SystemCoreClock/4);

stevestrong Fri May 05, 2017 6:11 pm

Good news, it started to work with libmaple code, the scope shows the SPI_CLK pulses (SPI3), and it does not freezes anymore.
Now need to determine which of my changes made it.
More to come.

michael_l Fri May 05, 2017 8:09 pm

stevestrong wrote:Good news, it started to work with libmaple code, the scope shows the SPI_CLK pulses (SPI3), and it does not freezes anymore.
Now need to determine which of my changes made it.
More to come.

stevestrong Sun May 07, 2017 3:22 pm

The actual bench values using SdFat beta, SPI3 21MHz, no DMA, card: 16GB SanDisk ultra class 10:
Type any character to start
FreeStack: 117044
Type is FAT32
Card size: 15.93 GB (GB = 1E9 bytes)

Manufacturer ID: 0X3
OEM ID: SD
Product: SL16G
Version: 8.0
Serial number: 0X72F2CA43
Manufacturing date: 8/2015

File size 5 MB
Buffer size 512 bytes
Starting write test, please wait.

write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
375.32,122150,759,1363
387.66,18954,1021,1319

Starting read test, please wait.

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
945.83,1574,529,540
946.01,1071,529,540

Done

ag123 Sun May 07, 2017 4:41 pm

+5 good achievement :D

writing speed seem to have reached sd native limiting speed, for read speed, my thoughts are that if a bigger buffer is used e.g. 1k it may narrow the difference so much that DMA would not make too much difference

stevestrong Sun May 07, 2017 5:39 pm

It seems that a buffer size of 4096 or 8182 is the best option if RAM is tidy (see table of the next post).

stevestrong Sun May 07, 2017 10:20 pm

I have completed the table with bench results using SPI = 42MHz, all without DMA.
stm32_sd_performance.jpg
stm32_sd_performance.jpg (162.89 KiB) Viewed 921 times

ag123 Mon May 08, 2017 8:46 am

the improvement in write speeds is really dramatic going up to 4k, 8k :D

stevestrong Mon May 08, 2017 8:50 am

Yes, if you reserve 32k buffer for it…
But even with 8k buffer it gives a nice speed.

Pito Mon May 08, 2017 8:56 am

SdBench with F4 must give you ~4.5MB/sec rd/wr @42MHz SPI clock and SdFatEX with 512bytes large buffer and DMA on..
SdBench with F1 must give you ~3.5MB/sec rd/wr @36MHz SPI clock and SdFatEX with 512bytes large buffer and DMA on..

stevestrong Mon May 08, 2017 9:02 am

Pito, the Ex didn’t bring any improvement.

I don’t see any way how to increase 10 times the rd/wr speed…
Can you hint to any solution?

Pito Mon May 08, 2017 9:05 am

You must switch the SdFatEX on in SdFatConfig.h.
Again, the above results are real..

stevestrong Mon May 08, 2017 9:07 am

Can you please post your test sketch + used core + SdFat lib?

Oh, and send me a similar card you are using :)
Btw, which color is your Sammy card? red or yellow/orange?

Pito Mon May 08, 2017 9:23 am

SdBench from latest SdFat is the sketch.
The cards I have used are:
1. Samsung EVO 8GB, CL10 UHS-I (white/orange) – works 21, 36, 42MHz
2. Sandisk Ultra 16GB, CL10 (red/grey) – works 21, 36MHz
If you do not get such results (plus minus 0.2MB/sec) then it is something wrong with your setup/settings/SPI_DMA driver..
The same results I get with Daniel’s core, and with libmaple.
With SdFatEX use 512bytes large buffer.

stevestrong Mon May 08, 2017 9:24 am

That’s why I’m asking you to post your setup, to be able to reproduce your results.
You can also send me BIN files for blue pill and/or maple mini and/or black F4 + indicate the used SPI and CS pins for each board in part.

Pito Mon May 08, 2017 9:45 am

Try – MapleMini, cs=PB12, SPI1, 36MHz, USB serial, bootloader20, SdFatEX, DMA, 512bytes large buffer

You have to get something like:
File size 5 MB
Buffer size 512 bytes
Starting write test, please wait.

write speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
3533.34,25083,136,143
3594.74,15522,136,141

Starting read test, please wait.

read speed and latency
speed,max,min,avg
KB/Sec,usec,usec,usec
3257.12,1548,155,156
3258.89,1359,155,156

Done
Type any character to start

stevestrong Mon May 08, 2017 11:33 am

What is the reason not to use F407 black SPI1 with 42MHz?

Pito Mon May 08, 2017 11:45 am

Try with 21, and when ok you will get 42 :)
FYI – the min Latency is the time you need to transfer 512bytes to the Sdcard. From above results:
136us/512/8 = 33.2ns -> 30MHz
207us/512/8 = 50.5ns -> 19.8MHz

Sign in to reply