Fast SPI on stm32f103cbt6

stm32_discoverer
Sun Jan 01, 2017 10:59 am
Hi guys, I have read that spi stm32f104cbt6 can operate at a frequency of 36 MHz, but the standard initialization of spi mode in the Arduino IDE provides only 18 MHz speed. This CPU has 2 SPI hardware interface, but as I understand only one of them works at the speed of 36 MHz.Here is standard init code from ARDUINO IDE – STM32F1 LIBRARY.Are there any settings SPI to work at the speed of 36 MHz ?I’m using Arduino IDE 1.6.5.
#include <SPI.h>

#define SPI1_NSS_PIN PA4 //SPI_1 Chip Select pin is PA4. You can change it to the STM32 pin you want.
#define SPI2_NSS_PIN PB12 //SPI_2 Chip Select pin is PB12. You can change it to the STM32 pin you want.

SPIClass SPI_2(2); //Create an instance of the SPI Class called SPI_2 that uses the 2nd SPI Port
byte data;

void setup() {

// Setup SPI 1
SPI.begin(); //Initialize the SPI_1 port.
SPI.setBitOrder(MSBFIRST); // Set the SPI_1 bit order
SPI.setDataMode(SPI_MODE0); //Set the SPI_2 data mode 0
SPI.setClockDivider(SPI_CLOCK_DIV2); // Slow speed (72 / 16 = 4.5 MHz SPI_1 speed)
pinMode(SPI1_NSS_PIN, OUTPUT);

// Setup SPI 2
SPI_2.begin(); //Initialize the SPI_2 port.
SPI_2.setBitOrder(MSBFIRST); // Set the SPI_2 bit order
SPI_2.setDataMode(SPI_MODE0); //Set the SPI_2 data mode 0
SPI_2.setClockDivider(SPI_CLOCK_DIV2); // Use a different speed to SPI 1
pinMode(SPI2_NSS_PIN, OUTPUT);

}


Pito
Sun Jan 01, 2017 11:56 am
http://www.stm32duino.com/viewtopic.php?t=1495#p19393

With SPI1
SPI.setClockDivider(SPI_CLOCK_DIV2); // (72 MHz / 2 = 36MHz)


stm32_discoverer
Sun Jan 01, 2017 12:22 pm
Ok, i’m trying to do some test about it, and what have we got?
void loop() {
duration=micros();
for (int i=0;i<1000;i++){
data = SPI.transfer(0xFF);
}
duration=micros()-duration;
Serial.println(duration);
}

Pito
Sun Jan 01, 2017 12:25 pm
You have to subtract the for_loop timing.. Also the call to the transfer function takes some time.
You will not get exact 2x speedup, of course.
Best is to look at SPI clock with an LA or an O’scope.
Btw, to transfer 1000bytes @ 36MHz shall take about 250usecs (overhead exclusive)..

stm32_discoverer
Sun Jan 01, 2017 12:35 pm
what about SPI with DMA.–°ould this increase the transfer speed?

stm32_discoverer
Sun Jan 01, 2017 12:43 pm
in fact, we have to transfer 1000 bytes 1312 microseconds, I think that is too much

Pito
Sun Jan 01, 2017 1:05 pm
FYI – with your code above

SPI12 TRX vs Clk.JPG
SPI12 TRX vs Clk.JPG (69.82 KiB) Viewed 1146 times

stm32_discoverer
Sun Jan 01, 2017 1:23 pm
thank’s for the visual representation, but how to speed up the transfer of SPI1, at least up to 2x

Pito
Sun Jan 01, 2017 1:38 pm
:idea:
1. Use DMA
2. Optimize the SPI.transfer() [ie. unroll the loop, use SPI Fifo if available, etc.] 3. Use F407+

danieleff
Sun Jan 01, 2017 1:48 pm
stm32_discoverer wrote:thank’s for the visual representation, but how to speed up the transfer of SPI1, at least up to 2x

Pito
Sun Jan 01, 2017 2:06 pm
Updated Table with SPI.write(buf,size).

stm32_discoverer
Sun Jan 01, 2017 2:20 pm
but how activate DMA transfer on SPI1?

Pito
Sun Jan 01, 2017 2:21 pm
Updated Table with SPI.dmaTransfer(buft, bufr, 1000) transfer timings :)

uint8 bfs[1000];
uint8 bfr[1000];

void loop() {
uint32 duration = micros();

// for (int i = 0; i < 1000; i++){
// data = SPI.transfer(0xFF);
// }

// SPI.write(bfs, 1000);

SPI.dmaTransfer(bfs, bfr, 1000);

duration = micros() - duration;
Serial.println(duration);
}


stm32_discoverer
Sun Jan 01, 2017 2:26 pm
Pito wrote:Updated Table with SPI.dmaTransfer(buft, bufr, 1000) transfer timings :)

stm32_discoverer
Sun Jan 01, 2017 3:05 pm
bufs and buft in SPI.dmaTransfer should be the same size?

Pito
Sun Jan 01, 2017 3:29 pm
SPI sends and receives in parallel, so the buffers shall be the same size.

Not sure how the function
uint8 dmaTransfer(uint8 *transmitBuf, uint8 *receiveBuf, uint16 length);
actually works – as it is seems from timing it is blocking.
My understanding would be you shoot out the data via SPI.dmaTransfer() and do other things afterwards ..


stm32_discoverer
Sun Jan 01, 2017 3:41 pm
thank you very much for the info ;)

stevestrong
Sun Jan 01, 2017 4:39 pm
danieleff wrote:I do not know why is it not called SPI.transfer(buffer, size) like in the arduino reference.

Leave a Reply

Your email address will not be published. Required fields are marked *