-
Notifications
You must be signed in to change notification settings - Fork 79
suboptimal SPI usage in write function on Nucleo platform #28
Description
-
Arduino board: Nucleo
-
Arduino IDE version: 1.8.5
I am working on with Nucleo board and since stm32's SPI setup is more complex (than setting couple of registers) calling SPI.beginTransaction
causes long delays in communication.
Transfer requires at least one call to beginTransaction
so theoretically it should be enough.
How does it look like in practice? After uploading WebServer
example and fetching data in browser, developer tools are showing 600-700 ms of waiting time.
I've plugged in logic analyzer and used one pin for time tracing.
uint8_t W5500Class::write(uint16_t _addr, uint8_t _cb, uint8_t _data)
{
digitalWrite(D8, HIGH);
SPI.beginTransaction(wiznet_SPI_settings);
setSS();
SPI.transfer(_addr >> 8);
SPI.transfer(_addr & 0xFF);
SPI.transfer(_cb);
SPI.transfer(_data);
resetSS();
SPI.endTransaction();
digitalWrite(D8, LOW);
return 1;
}
uint16_t W5500Class::write(uint16_t _addr, uint8_t _cb, const uint8_t *_buf, uint16_t _len)
{
digitalWrite(D8, HIGH);
SPI.beginTransaction(wiznet_SPI_settings);
setSS();
SPI.transfer(_addr >> 8);
SPI.transfer(_addr & 0xFF);
SPI.transfer(_cb);
for (uint16_t i=0; i<_len; i++){
SPI.transfer(_buf[i]);
}
resetSS();
SPI.endTransaction();
digitalWrite(D8, LOW);
return _len;
}
Here is result:
By checking slopes of D8 and CS you can see that beginTransaction
takes about 45 µs and takes longer than reset of function...
After commenting out beginTransaction
and endTransaction
I managed to halve the time needed for page load (around 260ms), and timing looks as follow:
I checked the same on Arduino Nano and there were no observable time differences w/ w/o beginTransaction
(around 230 ms):
If one is curious: this is SPI initialization on avr (yes, those two lines), and for Nucleo here is call to spi_init
which looks like this on stm32duino...