arduino / docs-content

Arduino documentation (docs.arduino.cc)
https://docs.arduino.cc/
Creative Commons Attribution Share Alike 4.0 International
156 stars 367 forks source link

missing documentation and example code: how to quickly and permanently change SPI clock divider #389

Open shiftleftplusone opened 9 years ago

shiftleftplusone commented 9 years ago

missing documentation and example code: how to quickly and simply change SPI clock divider ? About setClockDivider(): "This function should not be used in new projects. Use SPISettings with SPI.beginTransaction() to configure SPI parameters."

But I don't understand how to use SPI.beginTransaction() or either function for AVR, and ARM, and ARM extended mode. More source code examples would be needed for this.

cmaglie commented 9 years ago

Is the following useful for you?

https://www.arduino.cc/en/Tutorial/SPITransaction

shiftleftplusone commented 9 years ago

thank you, I already checked this. What I am actually looking for is a command like

setup() {
  setSPIClockDivider(2); // SPI on AVR = 16MHz/2=8MHz
  //..
}

to setup SPI on AVRs to 8MHz and make it work for all attached devices (e.g., SPI TFTs and SD cards) at this clock speed, at once and for all.

The same for either Due mode (standard or extended):

setSPIClockDivider(7); // SPI on ARM = 84MHz/7=12MHz
cmaglie commented 9 years ago

the closest equivalent for AVR to:

SPI.setClockDivider(2);

is:

SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
SPI.endTransaction();

By the way you should re-think your software design because using the same clock speed for all the SPI devices means that they all go at the speed of the slowest, even if they can go much faster.

shiftleftplusone commented 9 years ago

most of all my devices seem to work at 4MHz, especially TFTs which often are far too slow. I just want to make them work as fast as possible, surely I have to test the limits then and re-define it. I don't write own SPI code.

But what about Due and Due extended mode?

cmaglie commented 9 years ago

Bur what about Due and Due extended mode?

It's the same code. Moreover you don't need to worry about the "divisor" to obtain the desired frequency, because SPISettings does the math for you.

shiftleftplusone commented 9 years ago

aaahh, thanks, that's fine. This explanation would be appreciated if added to the function reference! Thank you for your input!

shiftleftplusone commented 9 years ago

ps, and then

SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
SPI.endTransaction();

would work for all attached devices at once, no matter how many there are currently, like TFT(s) and SD slots?

PaulStoffregen commented 9 years ago

This explanation would be appreciated if added to the function reference!

The reference page does have this text: https://www.arduino.cc/en/Reference/SPI

"What is the maximum SPI speed your device can use? This is controlled by the first parameter in SPISettings. If you are using a chip rated at 15 MHz, use 15000000. Arduino will automatically use the best speed that is equal to or less than the number you use with SPISettings."

shiftleftplusone commented 9 years ago

but not this reference page: https://www.arduino.cc/en/Tutorial/SPITransaction

shiftleftplusone commented 9 years ago

now what confuses me is: " Your settings remain in effect for the duration of your "transaction". "

But I don't want to limit the clock speed to the duration of any "transaction", I want to set it once and for all transactions, for the whole program, the same way I'm setting Serial.begin(BAUDRATE) once and for all

cmaglie commented 9 years ago

Your settings remain in effect for the duration of your "transaction".

The wording is a bit misleading it should be: the SPI settings are applied at the begin of the transaction and endTransaction() doesn't change SPI settings.

Unless you, or some library, calls beginTransaction a second time, the setting are maintained.

shiftleftplusone commented 9 years ago

thank you, now it's clear to me (I hope) ;)

shiftleftplusone commented 9 years ago

...not quite though, I'm afraid..:

let's say, I #include SD.h and Adafruit_ILI9340.h and Adafruit_GFX.h and Pixycam.h and whatever. Now I actually have no control over anything what happens in these libs, e.g. if they call beginTransaction once or twice or repeatedly. So it might happen (CMIIW) that a device lib overwrites my setting at any time. But I want to set 8MHz once and for all libs and all devices and block all individual device settings - what is the command to maintain my personal settings all over the time regardles what's written in either lib?

matthijskooijman commented 9 years ago

let's say, I #include SD.h and Adafruit_ILI9340.h and Adafruit_GFX.h and Pixycam.h and whatever. Now I actually have no control over anything what happens in these libs, e.g. if they call beginTransaction once or twice or repeatedly. So it might happen (CMIIW) that a device lib overwrites my setting at any time.

Yes, and this is exactly what begin/endTransaction are intended to solve. If, before writing anything to SPI, you call beginTransaction with the settings needed for the device you are writing to, and call endTransaction when you're finished writing for now, every device will get its own settings applied at the right times.

But I want to set 8MHz once and for all libs and all devices and block all individual device settings - what is the command to maintain my personal settings all over the time regardles what's written in either lib?

I do not think the SPI library supports this right now. I also am not so sure if this is really useful or should be added. Can you motivate why you want this exactly? If every lib uses correct SPI settings, everything will just work?

If you really want this right now, I think you either have to modify the SPI library and modify beginTransaction to not change the settings, or modify the libraries to not call beginTransaction.

shiftleftplusone commented 9 years ago

the reason is simply that all my TFTs are insanely lame, and I want to increase SPI speed as much as possible to accelerate screen output. Also to some SD file readings/writings it wouldn't hurt if they run quicker. Nevertheless I surely will have to check if other devices plugged to the same bus will tolerate this higher speed, too. But the more devices being plugged to the SPI bus the more a speed enhancement will become necessary. I assume that some libs once have been designed for standard hardware providing limited performance, but actual hardware development might have progressed. E.g., I2C bus is clocked at standard 100kHz, but many I2C devices also run high speed I2C at 400kHz or almost 1MHz clock. OTOH, many wireless modules (e.g. 3DR radio modules) are clocked at 9600 BAUD by default, but also support to be clocked at up to 256000 BAUD just by firmware setting.

So I will try to test if my TFTs and my SD card backpanes wouldn't support "high speed SPI" generally to achieve over all a better performance, regardless of default SPI driver lib settings. Finally it's not so much different from overclocking a graphic card, PC clock in the BIOS, or a RaspPi .

matthijskooijman commented 9 years ago

I guess the proper solution to your problem is to modify the library to use a higher speed, or if that is not unconditionally possible, modify the library so it allows configuring the SPI speed to use from the sketch.

shiftleftplusone commented 9 years ago

Then the number of SPI libs which then had to be patched is Legion. More over, for this task I'm a too stupid end user, I even have no idea about how SPI works at all.

So I would appreciate to have a generally working SPIclockdivider or a SetSPIClockSpeed function in order to set a general SPI clock speed. That's what I actually had in my mind with my TOP.

PaulStoffregen commented 9 years ago

So I would appreciate to have a generally working SPIclockdivider or a SetSPIClockSpeed function in order to set a general SPI clock speed.

SPI.setClockDivider() should not be used in new projects.

SPI.beginTransaction() is the proper way to configure SPI speed.

I even have no idea about how SPI works at all.

Matthijs and Cristian and I do have a very good understanding of exactly how SPI works. Over the last couple years, we have put a lot of work into improving the SPI library.

You should trust our engineering decisions and follow the published advice.

shiftleftplusone commented 9 years ago

Please read closely again:

"Then the number of SPI libs which then had to be patched is Legion (i.e., countless). More over, for this task (i.e., to patch innumerable exsting and future SPI device drivers) I'm a too stupid end user, I even have no idea about how SPI works at all.

So I would appreciate >>>> to have a generally working (i.e., ongoing, for all) SPIclockdivider or a SetSPIClockSpeed function in order to set a general (i.e., static, fixated) SPI clock speed <<<< . That's what I actually had in my mind with my TOP."

jcarolinares commented 3 months ago

Hello, this is outdated and open for more than 9 years.

I think is a discussion more related at this moment to the arduino forum

@jacobhylen idem, I suggest to close this issue