Re: Painfully slow SPI on STM32F405
Posted: Sat Aug 01, 2020 12:38 am
Unfortunately I checked this and it did not work. I looked on my scope and I'm not getting any data on the SPI lines. I'm using SPI1, which is PB3 - PB5, correct?Bakisha wrote: Fri Jul 31, 2020 11:59 pm I finally found solution. After dive into CMSIS definitions of the core, and testing it on logic analyzer with STM32F401CC (84MHz) , i found that error was on my part, because in my case, i had CE not going high after transfer (i had some more stuff execution) , and in this case CE will go high while hardware is still sending last byte. So, here is a macro for sending a byte:
But, i was correct that gaps between bytes normal SPI.transfer was around 2uS.Code: Select all
void SPI_TRANSFER (uint8_t x) { // SPI.transfer(x); // send byte SPI1->DR = (x) ; while ((SPI1->SR & SPI_SR_BSY ) | (SPI1->SR & (!SPI_SR_TXE)) ) {}; // wait until - Transmit buffer NOT Empty - Busy flag SET }
Also, i found that 17uS was just for SPI.beginTransaction and SPI.endTransaction
Also, digitalWrite is around 0.5uS
Here is sketch that used to get maximum speed :
And here is screenshot of logic analyzer of that sketch (ignore CLK and MOSI, 24MHz samplerate is to slow for 42MHz spi clock, but is enough for CE time) :Code: Select all
#include <SPI.h> #define CS PA4 int i = 0; void setup() { pinMode(CS, OUTPUT); digitalWrite(CS, HIGH); SPI.begin(); SPI.beginTransaction(SPISettings(50000000, MSBFIRST, SPI_MODE0)); } void loop() { i++; if (i > 1023) { i = 0; } dac8Write(1, i); } void dac8Write(byte channel, int input) { //Warning: Channel must be less than 7! //0011 Command - Write to and Update DAC //0xxx Address - Binary address of DAC's 1-8 //xxxxxxxxxx - 10 bit analog value channel = 0x30 | channel; input = input << 6; // Send as command, address, then 10 bit value digitalWrite(CS, LOW); SPI_TRANSFER(channel); SPI_TRANSFER(highByte(input)); SPI_TRANSFER(lowByte(input)); digitalWrite(CS, HIGH); } void SPI_TRANSFER (uint8_t x) { // 0.3uS overhead between bytes when optimized // 3.25 uS unoptimized // SPI.transfer(x); // send byte SPI1->DR = (x) ; while ((SPI1->SR & SPI_SR_BSY ) | (SPI1->SR & (!SPI_SR_TXE)) ) {}; // wait until - Transmit buffer NOT Empty - Busy flag SET }
I hope that is only device on SPI1 bus, or things might get complicated.