[SOLVED] Select the SPI bus within a function

Post here first, or if you can't find a relevant section!
Post Reply
aster
Posts: 110
Joined: Thu Mar 30, 2017 2:41 pm
Location: bella italy
Contact:

[SOLVED] Select the SPI bus within a function

Post by aster » Sat Nov 18, 2017 1:12 pm

Hello,
I try to explain the title of the topic. I have a library which use spi, but to select spi1 or 2 i need to edit the .cpp file
I would like to do it with a function, i tried it but i get errors since the declaration of "SPIClass SPI_bus(2);" seems to need to be declared as global

Any simple workaround or am i missing something?

victor_pv
Posts: 1738
Joined: Mon Apr 27, 2015 12:12 pm

Re: Select the SPI bus within a function

Post by victor_pv » Sat Nov 18, 2017 2:21 pm

You could try using a pointer to SPI instead, then the pointer can be changed in a function to one port or the other.
Within your code you will likely have to change all spi.transfer etc to spi->tranfer (so -> rather than .)

Example:
Original

Code: Select all

spi.transfer(xx,nn);
New:

Code: Select all

SPIClass *spi_pointer = &SPI;
...
spi_pointer->transfer(xx,nn);
And you can add a new function to change the value of spi_pointer any time to a different pointer. Make sure it's always valid so your code doesn't crash.
I believe Steve linked to a new ILI9341 driver where he implemented that. I have done similar in another driver. Here I change the value of the pointer in begin(SPIClass* spi):
https://github.com/victorpv/reflowOvenC ... 63C.h#L316

So in my code I can have for example SPI2 declared, to be the second port, then I can do this:

Code: Select all

tft.begin(&SPI2);
SPI2 is declared global in my main sketch, only the pointer is passed to the tft class. In my opinion SPI port objects (any hardware for tht matter) should always be global, since if you declare 2 copies of the same object to manage the same hardware decide, you are likely end up with unexpected results when both make changes to hardware registers that exist only once from 2 different places, each expecting their value to not be changed by another piece of code.

stevestrong
Posts: 1813
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: Select the SPI bus within a function

Post by stevestrong » Sat Nov 18, 2017 2:36 pm

Another example from here: https://github.com/stevstrong/Ethernet_STM32

You have to declare an SPI class object with appropriate SPI port number (1 or 2 for F1, 1..3 for F4)

Code: Select all

SPIClass mSpi(1); // you can use 1..2 for F1, 1..3 for F4)
Then you need to call a function in setup():

Code: Select all

Ethernet.init(mSpi, PA4); // SPI class object, chip select pin on your choice
Here, the SPI object will be passed as reference and not as pointer, so you must not use "->" the source:

Code: Select all

mSpi.transfer(0x55);

User avatar
RogerClark
Posts: 7437
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: Select the SPI bus within a function

Post by RogerClark » Sat Nov 18, 2017 7:01 pm

You may be able to use setModule(2)

see

viewtopic.php?t=423

aster
Posts: 110
Joined: Thu Mar 30, 2017 2:41 pm
Location: bella italy
Contact:

Re: Select the SPI bus within a function

Post by aster » Tue Nov 21, 2017 6:30 pm

thank very much to victor, stevestrong and roger
at the end since it wasn't my library and i didn't want to override the structure too much i used setModule but your solution are very interesting!

Post Reply