using SPI1 and SPI2 Simultaneous for w5500 and ILI9341

Post here first, or if you can't find a relevant section!
aryan.ir
Posts: 7
Joined: Wed Mar 23, 2022 3:05 pm

using SPI1 and SPI2 Simultaneous for w5500 and ILI9341

Post by aryan.ir »

Hello everybody. i create one pcb board for use ILI9341 and W5500 Simultaneously.i want show analog value on lcd and send it with w5500 udp.
MCU: STM32F103C8

ILI9341
LIB: "Adafruit_GFX.h" "Adafruit_ILI9341.h"
wiring: SPI2 >> PB15,PB14,PB13
TFT_BL PB5
TFT_CS PB12
TFT_DC PB1
TFT_RST PB0

w5500
LIB: <Ethernet.h> <EthernetUdp.h>
wiring: SPI1 >> PA7,PA6,PA5
CS PA4

The problem is that whatever I do, I can not use both at the same time. In the setup section, after installing one, when initializing the second, the first one fails. If I change their place during initializing, the first one will fail again during the second initialization. The point is that when I comment on the last initialization, the first part alone works fine.

I read and used all the following texts. But the problem remains.

((in setup() call SPI.setModule(2); before doing any other SPI activities.
SPI.setModule(2);

e.g.
SPI.setModule(2);
SPI.setClockDivider(SPI_CLOCK_DIV32);

Then the SPI pins for hardware SPI2 will be used by "SPI"

A better way to use more than one SPI device at the same time is to have a separate variable for the second SPI device

e.g.
SPIClass SecondSPI(2);
SecondSPI.setClockDivider(SPI_CLOCK_DIV32);
// etc etc
Unfortunately, you cant use the variable SPI2, as SPI1, SPI2 and SPI3 are internal variables in the core related to the hardware SPI devices. But you can use SPI_2 , SPI_3 .))


my code for test is:

Code: Select all

#include <SPI.h>         // needed for Arduino versions later than 0018
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <Ethernet.h>
#include <EthernetUdp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008

//---------------------------------------- Ethernet -------------------------------------------
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; // W5500 MAC Address
unsigned int localPort = 8888;   // W5500 port
IPAddress remote_ip(192, 168, 0, 103);
unsigned int remote_Port = 9999;
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

//------------------------------------------ ILI9341 --------------------------------------------------------
boolean TFT_BL = false ;
// For the Adafruit shield, these are the default
#define TFT_BL  PB5
#define TFT_CS  PB12
#define TFT_DC  PB1
#define TFT_RST PB0
// Only use Hardware SPI (Declare RST is important)
//Adafruit_ILI9341 tft = Adafruit_ILI9341 (TFT_CS, TFT_DC, TFT_RST); // Use hardware SPI
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); // Use hardware SPI

void setup() {
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH); //Turn Backlight ON

  Serial.begin(9600);
  delay(1000);

  Serial.print("START ...");

  //------------------------------------ Initial ILI9341 --------------------------------
  SPI.setModule(2);          // use SPI2
  tft.begin();

  tft.fillScreen(ILI9341_BLACK);
  tft.fillScreen(ILI9341_RED);
  tft.fillScreen(ILI9341_GREEN);
  tft.fillScreen(ILI9341_BLUE);
  tft.fillScreen(ILI9341_BLACK);

  //------------------------------------ Initial Ethernet --------------------------------
  SPI.setModule(1);          // use SPI1
  Ethernet.init(PA4);
  Ethernet.begin(mac);
  // start UDP
  Udp.begin(localPort);

  // print your local IP address:
  Serial.print("Ethernet.localIP: ");
  Serial.println(Ethernet.localIP());
  Serial.print("Ethernet.subnetMask: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("Ethernet.gatewayIP: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("Ethernet.dnsServerIP: ");
  Serial.println(Ethernet.dnsServerIP());
  Serial.print("Ethernet.localPort: ");
  Serial.println(localPort);
  Serial.println("-------------------------------------------------");

}
void loop(void) {

  // print your local IP address for check
  Serial.print("Ethernet.localIP: ");
  Serial.println(Ethernet.localIP());
  Serial.print("Ethernet.subnetMask: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("Ethernet.gatewayIP: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("Ethernet.dnsServerIP: ");
  Serial.println(Ethernet.dnsServerIP());
  Serial.print("Ethernet.localPort: ");
  Serial.println(localPort);
  Serial.println("-------------------------------------------------");

  //for check lcd
  tft.fillScreen(ILI9341_BLACK);
  tft.fillScreen(ILI9341_RED);
  tft.fillScreen(ILI9341_GREEN);
  tft.fillScreen(ILI9341_BLUE);
  tft.fillScreen(ILI9341_BLACK);

}
Last edited by aryan.ir on Wed Mar 23, 2022 4:35 pm, edited 1 time in total.
GonzoG
Posts: 403
Joined: Wed Jan 15, 2020 11:30 am
Answers: 27
Location: Prudnik, Poland

Re: using SPI1 and SPI2 Simultaneous for w5500 and ILI9341

Post by GonzoG »

Why you're using "enegria" as a source for information about STM32duino ??
https://github.com/stm32duino/wiki/wiki/API#spi
aryan.ir
Posts: 7
Joined: Wed Mar 23, 2022 3:05 pm

Re: using SPI1 and SPI2 Simultaneous for w5500 and ILI9341

Post by aryan.ir »

I used these other two libraries according to the attached files that have the ability to define a SPI number during initialization. But the same thing happens again. After installing the second part, the first part will fail. For example, if I start LCD(ILI9341) first, it works fine. But after executing the codes related to ethernet and initializing it, The LCD will be fail. If I replace the first part initializing with second parts, it will be the same result that first module dont work .

Code: Select all

#include <SPI.h>         // needed for Arduino versions later than 0018
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341_STM.h"
#include <Ethernet_STM32.h>
#include <EthernetUdp.h>         

SPIClass SPI_1(1); // use SPI1
SPIClass SPI_2(2); // use SPI2

//---------------------------------------- Ethernet -------------------------------------------
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; // W5500 MAC Address
unsigned int localPort = 8888;   // W5500 port
IPAddress remote_ip(192, 168, 0, 103);
unsigned int remote_Port = 9999;
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

//------------------------------------------ ILI9341 --------------------------------------------------------
boolean TFT_BL = false ;
// For the Adafruit shield, these are the default
#define TFT_BL  PB5
#define TFT_CS  PB12
#define TFT_DC  PB1
#define TFT_RST PB0

// Only use Hardware SPI (Declare RST is important)
Adafruit_ILI9341_STM tft = Adafruit_ILI9341_STM(TFT_CS, TFT_DC, TFT_RST); // Use hardware SPI


void setup() {
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH); //Turn Backlight ON

  Serial.begin(9600);
  delay(1000);

  Serial.print("START ...");

  //------------------------------------ Initial ILI9341 --------------------------------
  tft.begin(SPI_2);  // set ILI9341 at SPI2

  tft.fillScreen(ILI9341_BLACK);
  tft.fillScreen(ILI9341_RED);
  tft.fillScreen(ILI9341_GREEN);
  tft.fillScreen(ILI9341_BLUE);
  tft.fillScreen(ILI9341_BLACK);

  //------------------------------------ Initial Ethernet --------------------------------
  Ethernet.init(SPI_1, PA4); //set W5500 at SPI1 and CS:PA4
  Ethernet.begin(mac);
  // start UDP
  Udp.begin(localPort);

  // print your local IP address:
  Serial.print("Ethernet.localIP: ");
  Serial.println(Ethernet.localIP());
  Serial.print("Ethernet.subnetMask: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("Ethernet.gatewayIP: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("Ethernet.dnsServerIP: ");
  Serial.println(Ethernet.dnsServerIP());
  Serial.print("Ethernet.localPort: ");
  Serial.println(localPort);
  Serial.println("-------------------------------------------------");

}
void loop(void) {

  // print your local IP address for check
  Serial.print("Ethernet.localIP: ");
  Serial.println(Ethernet.localIP());
  Serial.print("Ethernet.subnetMask: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("Ethernet.gatewayIP: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("Ethernet.dnsServerIP: ");
  Serial.println(Ethernet.dnsServerIP());
  Serial.print("Ethernet.localPort: ");
  Serial.println(localPort);
  Serial.println("-------------------------------------------------");

  //for check lcd
  tft.fillScreen(ILI9341_BLACK);
  tft.fillScreen(ILI9341_RED);
  tft.fillScreen(ILI9341_GREEN);
  tft.fillScreen(ILI9341_BLUE);
  tft.fillScreen(ILI9341_BLACK);

}
The proposed solution of [ SPIClass SPI_1(1); SPIClass SPI_2(2); ] does not solve the problem either.
I think the reason for the failure of the first module after installing the second module is that the SPIs are mixed together, although they are defined separately. Is there another solution that can use two SPI simultaneously and separately?
Attachments
Ethernet_STM32.rar
(44.75 KiB) Downloaded 131 times
Adafruit_ILI9341_STM.rar
(32.73 KiB) Downloaded 108 times
BennehBoy
Posts: 135
Joined: Sat Jan 04, 2020 2:38 am
Answers: 1

Re: using SPI1 and SPI2 Simultaneous for w5500 and ILI9341

Post by BennehBoy »

Are you sure it's not the ILI9341 or Ethernet library that's at fault? I've had many problems with the Adafruit libs making assumptions about which SPI peripheral is being used and with what settings in the past.

I'm currently using a MAX31856 & an SSD3106 without issue on 2 different SPI ports of various stm32 devices, so I don't think it's a core issue.
aryan.ir
Posts: 7
Joined: Wed Mar 23, 2022 3:05 pm

Re: using SPI1 and SPI2 Simultaneous for w5500 and ILI9341

Post by aryan.ir »

I'm sure the libraries are OK because Each one of them works properly alone. I even tested it on the breadboard. Each one works Correctly on any spi1 and spi2, But in the program, you can not use both at the same time. As soon as you use another, the previous one fails. I also used the adafruit library set up for stm mcu.
BennehBoy
Posts: 135
Joined: Sat Jan 04, 2020 2:38 am
Answers: 1

Re: using SPI1 and SPI2 Simultaneous for w5500 and ILI9341

Post by BennehBoy »

The fact that they work independently does not mean that they will work together.
aryan.ir
Posts: 7
Joined: Wed Mar 23, 2022 3:05 pm

Re: using SPI1 and SPI2 Simultaneous for w5500 and ILI9341

Post by aryan.ir »

Does it means we can not use spi1 and spi2 simultaneously for two different modules?
GonzoG
Posts: 403
Joined: Wed Jan 15, 2020 11:30 am
Answers: 27
Location: Prudnik, Poland

Re: using SPI1 and SPI2 Simultaneous for w5500 and ILI9341

Post by GonzoG »

No. It does not.
It means that those 2 libraries don't want to work together.

As BennehBoy said, you can use different SPI interfaces.
I'm also using 2 SPIs for different devices (LCD and SD card) and it works without any problems.
ABOSTM
Posts: 60
Joined: Wed Jan 08, 2020 8:40 am
Answers: 7

Re: using SPI1 and SPI2 Simultaneous for w5500 and ILI9341

Post by ABOSTM »

Warning:
SPI.setModule(2);
Correspond to RogerClark's core
whereas https://github.com/stm32duino/wiki/wiki/API#spi
correspond to official STMicroelectronics core: Arduino_Core_STM32
and this setModule method doesn't exist in Arduino_Core_STM32
So which Core are you using ?

Concerning Arduino_Core_STM32 Core,
SPI is the default Arduino instance of object class SPIClass.
It is created automatically by default.
But if you want to work with a second spi instance, a second object is not created by default, so you need somehow to create a second object of class SPIClass.
see
https://github.com/stm32duino/wiki/wiki/API#spi
aryan.ir
Posts: 7
Joined: Wed Mar 23, 2022 3:05 pm

Re: using SPI1 and SPI2 Simultaneous for w5500 and ILI9341

Post by aryan.ir »

I also tested with the official core. ILI9341 is connected to SPI2 on the PCB board. With the official core, only the library "Adafruit_ILI9341_STM.h" was able to launch it. And the w5500 is also connected to SPI1. Which only the <Ethernet.h> library could launch it with official core. When I program the simultaneous use of both in the following code, there is the same problem as before.

Code: Select all

#include <SPI.h>         // needed for Arduino versions later than 0018
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341_STM.h"
#include <Ethernet.h>
#include <EthernetUdp.h>

//---------------------------------------- Ethernet -------------------------------------------
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; // W5500 MAC Address
unsigned int localPort = 8888;   // W5500 port
IPAddress remote_ip(192, 168, 0, 103);
unsigned int remote_Port = 9999;
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

//------------------------------------------ ILI9341 --------------------------------------------------------
boolean TFT_BL = false ;
// For the Adafruit shield, these are the default
#define TFT_BL  PB5
#define TFT_CS  PB12
#define TFT_DC  PB1
#define TFT_RST PB0

// Only use Hardware SPI (Declare RST is important)
Adafruit_ILI9341_STM tft = Adafruit_ILI9341_STM(TFT_CS, TFT_DC, TFT_RST); // Use hardware SPI


void setup() {
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH); //Turn Backlight ON

  Serial.begin(9600);
  delay(1000);

  Serial.print("START ...");

  //------------------------------------ Initial Ethernet --------------------------------
  Ethernet.init(PA4);
  Ethernet.begin(mac);
  // start UDP
  Udp.begin(localPort);

  // print your local IP address:
  Serial.print("Ethernet.localIP: ");
  Serial.println(Ethernet.localIP());
  Serial.print("Ethernet.subnetMask: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("Ethernet.gatewayIP: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("Ethernet.dnsServerIP: ");
  Serial.println(Ethernet.dnsServerIP());
  Serial.print("Ethernet.localPort: ");
  Serial.println(localPort);
  Serial.println("-------------------------------------------------");

  //------------------------------------ Initial ILI9341 --------------------------------
  SPIClass SPI_2(PB15, PB14, PB13);
  tft.begin(SPI_2,9000000);  // set direct frequency value in MHz

  tft.fillScreen(ILI9341_BLACK);
  tft.fillScreen(ILI9341_RED);
  tft.fillScreen(ILI9341_GREEN);
  tft.fillScreen(ILI9341_BLUE);
  tft.fillScreen(ILI9341_BLACK);


}
void loop(void) {

  // print your local IP address for check
  Serial.print("Ethernet.localIP: ");
  Serial.println(Ethernet.localIP());
  Serial.print("Ethernet.subnetMask: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("Ethernet.gatewayIP: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("Ethernet.dnsServerIP: ");
  Serial.println(Ethernet.dnsServerIP());
  Serial.print("Ethernet.localPort: ");
  Serial.println(localPort);
  Serial.println("-------------------------------------------------");

  //for check lcd
  tft.fillScreen(ILI9341_BLACK);
  tft.fillScreen(ILI9341_RED);
  tft.fillScreen(ILI9341_GREEN);
  tft.fillScreen(ILI9341_BLUE);
  tft.fillScreen(ILI9341_BLACK);

}
And i can not be used them simultaneously. Only the module that is initialized at the end, works properly.

If you have another library or can change the code, thank you very much.
Post Reply

Return to “General discussion”