SPI Not Useable

I have been trying to use the hardware SPI on the UNO WiFi R2. For example, this simple
program using the Adafruit RA8875 LCD Driver doesn't work at all on the UNO WiFi.

/******************************************************************
 This is an example for the Adafruit RA8875 Driver board for TFT displays
 ---------------> http://www.adafruit.com/products/1590
 The RA8875 is a TFT driver for up to 800x480 dotclock'd displays
 It is tested to work with displays in the Adafruit shop. Other displays
 may need timing adjustments and are not guanteed to work.

 Adafruit invests time and resources providing this open
 source code, please support Adafruit and open-source hardware
 by purchasing products from Adafruit!

 Written by Limor Fried/Ladyada for Adafruit Industries.
 BSD license, check license.txt for more information.
 All text above must be included in any redistribution.
 ******************************************************************/

#include <SPI.h>
#include "Adafruit_GFX.h"
#include "Adafruit_RA8875.h"


// Library only supports hardware SPI at this time
// Connect SCLK to UNO Digital #13 (Hardware SPI clock)
// Connect MISO to UNO Digital #12 (Hardware SPI MISO)
// Connect MOSI to UNO Digital #11 (Hardware SPI MOSI)
#define RA8875_INT 3
#define RA8875_CS 10
#define RA8875_RESET 9

Adafruit_RA8875 tft = Adafruit_RA8875(RA8875_CS, RA8875_RESET);
uint16_t tx, ty;

void setup()
{
  Serial.begin(9600);
  Serial.println("RA8875 start");

  /* Initialize the display using 'RA8875_480x80', 'RA8875_480x128', 'RA8875_480x272' or 'RA8875_800x480' */
  if (!tft.begin(RA8875_800x480)) {
    Serial.println("RA8875 Not Found!");
    while (1);
  }

  Serial.println("Found RA8875");

  tft.displayOn(true);
  tft.GPIOX(true);      // Enable TFT - display enable tied to GPIOX
  tft.PWM1config(true, RA8875_PWM_CLK_DIV1024); // PWM output for backlight
  tft.PWM1out(255);

  // With hardware accelleration this is instant
  tft.fillScreen(RA8875_WHITE);

  // Play with PWM
  for (uint8_t i=255; i!=0; i-=5 )
  {
    tft.PWM1out(i);
    delay(10);
  }
  for (uint8_t i=0; i!=255; i+=5 )
  {
    tft.PWM1out(i);
    delay(10);
  }
  tft.PWM1out(255);

  tft.fillScreen(RA8875_RED);
  delay(500);
  tft.fillScreen(RA8875_YELLOW);
  delay(500);
  tft.fillScreen(RA8875_GREEN);
  delay(500);
  tft.fillScreen(RA8875_CYAN);
  delay(500);
  tft.fillScreen(RA8875_MAGENTA);
  delay(500);
  tft.fillScreen(RA8875_BLACK);

  // Try some GFX acceleration!
  tft.drawCircle(100, 100, 50, RA8875_BLACK);
  tft.fillCircle(100, 100, 49, RA8875_GREEN);

  tft.fillRect(11, 11, 398, 198, RA8875_BLUE);
  tft.drawRect(10, 10, 400, 200, RA8875_GREEN);
  tft.fillRoundRect(200, 10, 200, 100, 10, RA8875_RED);
  tft.drawPixel(10,10,RA8875_BLACK);
  tft.drawPixel(11,11,RA8875_BLACK);
  tft.drawLine(10, 10, 200, 100, RA8875_RED);
  tft.drawTriangle(200, 15, 250, 100, 150, 125, RA8875_BLACK);
  tft.fillTriangle(200, 16, 249, 99, 151, 124, RA8875_YELLOW);
  tft.drawEllipse(300, 100, 100, 40, RA8875_BLACK);
  tft.fillEllipse(300, 100, 98, 38, RA8875_GREEN);
  // Argument 5 (curvePart) is a 2-bit value to control each corner (select 0, 1, 2, or 3)
  tft.drawCurve(50, 100, 80, 40, 2, RA8875_BLACK);
  tft.fillCurve(50, 100, 78, 38, 2, RA8875_WHITE);

  pinMode(RA8875_INT, INPUT);
  digitalWrite(RA8875_INT, HIGH);

  tft.touchEnable(true);

  Serial.print("Status: "); Serial.println(tft.readStatus(), HEX);
  Serial.println("Waiting for touch events ...");
}

void loop()
{
  float xScale = 1024.0F/tft.width();
  float yScale = 1024.0F/tft.height();

  /* Wait around for touch events */
  if (! digitalRead(RA8875_INT))
  {
    if (tft.touched())
    {
      Serial.print("Touch: ");
      tft.touchRead(&tx, &ty);
      Serial.print(tx); Serial.print(", "); Serial.println(ty);
      /* Draw a circle */
      tft.fillCircle((uint16_t)(tx/xScale), (uint16_t)(ty/yScale), 4, RA8875_WHITE);
    }
  }
}

but works just fine on the UNO R3. And, yes, I have checked, double checked and triple checked the wiring and the board selection in the IDE.

So, before I condemn this board as hopelessly useless, or defective, I want to ask if there is anything I'm missing. Although I have tried out the WiFi functions successfully, the current phase of this project is to get the board working with an SPI device WITHOUT the WiFi, for now.

I am not, at this point, loading any functions having to do with the WiFi section of the board...the software knows nothing about the WiFi hardware. Is it possible the WiFi hardware is interfering with the SPI hardware because I'm not initializing or setting-up the WiFi hardware? Eventually, the WiFi and the SPI will be needed together, but for now I need the SPI to work without the WiFi.

Any thoughts, anyone?

You are aware that pins 11, 12 and 13 are not the SPI interface on the Uno WiFi Rev2? The SPI pins are only available on the 6-pin header.

1 Like

On the contrary, the Pinout Diagram clearly shows pins 11, 12, and 13 as SPI pins. If this is not correct, then the Pinout diagram needs to be updated. And this board will be absolutley useless for my project.

On https://docs.arduino.cc/hardware/uno-wifi-rev2 is a link to the pinout:
https://docs.arduino.cc/static/d37f6b33c17c09612ff4ac7ce94fa68f/ABX00021-full-pinout.pdf

I can see where your confusion comes from (page 2). On the product page (ARDUINO UNO WiFi REV2 — Arduino Official Store) it however only shows the image of the first page but it does not mention the SPI pins :frowning:

I will report it.

May I ask why?

You missed pin 8 which is SS , your code has it on pin 10.

#define RA8875_CS 10

image

I have several IN-12 Nixie tube clock shields I purchased from Ukraine; currently I use the UNO R3 to run them; I would like to add WiFi capability so they can automatically connect to my WiFi router and reset themselves to the correct time. The UNO WiFi R3 seemed to be the easiest way to do this, but that was based on mis-information.

So, just how compatible will the UNO R4 actually be with the UNO R3? I've been looking forward to the release of the UNO R4, partly for this reason.

The SPI-related functions I use allow for the use of any pins for the chip-select (CS/SS).

The use of pin 8 would only be required if the functions required the use of the default chip-select.

You posted the question in Uno WiFi Rev2; so which board are we talking about?

Just a Side note:

I also tried abandoning SPI altogether and tried bit-banging pins 10, 11, 12, and 13. That didn't work either on the UNO WiFi R2; it did work on the UNO R3. Something weird is going on with those 3 or 4 pins.

The part of the pinout that you show comes from the second page of the full pinout. Try to match it to the schematic (https://docs.arduino.cc/static/d9043827f055a201be10101328efda18/schematics.pdf) :smiley:

Sorry, it's a typo, should be "The UNO WiFi R2". This whole thread is about the UNO WiFi R2...there is no UNO WiFi R3.

I know, I only wanted to make sure that we are on the same page.

Apology accepted :wink:

So those shields don't use / have the 6-pin female header.

I've seen a nixie shield once on a Mega and that worked; the Mega has the same problems as the Uno WiFi Rev2 that the SPI pins are not on 101/12/13. Maybe what I did see was a totally different shield that did not use SPI.

Do you have a link to the nixie shield?

About a month ago I did try to find schematics but could not find it. I however will not give you much hope that the SPI pins will be on 11/12/13; the standard nowadays is the R3 form factor with the 6-pin header.

I suspect that we have to wait till the end of May before we really know.

After looking at the schematic:

  • I would ensure that CS is HIGH for WIFI/BLE1 (PF2 = HIGH) to disable WIFI/BLE1 MISO.
  • Also ensure that CS is LOW for IMU1 (PB3 = LOW) to enable IMU1 MISO.

Looks like you would have to switch between WIFI and SPI.

To use SPI (untested):

  // disable MISO for WIFI/BLE1
  PORTF.DIRSET = PIN2_bm; // CS is an output
  PORTF.OUTSET = PIN2_bm; // CS is high

  // enable MISO for IMU1
  PORTB.DIRSET = PIN3_bm; // CS is an output
  PORTB.OUTCLR = PIN3_bm; // CS is low

To use WIFI (untested):

  // disable MISO for IMU1
  PORTB.DIRSET = PIN3_bm; // CS is an output
  PORTB.OUTSET = PIN3_bm; // CS is high

  // enable MISO for WIFI/BLE1
  PORTF.DIRSET = PIN2_bm; // CS is an output
  PORTF.OUTCLR = PIN2_bm; // CS is low

Better yet, use MegaCoreX
MegaCoreX currently supports pinswapping the SPI, i2c and UART peripheral pins.

No, they don't. The shields can use the UNO or the MEGA 2560; neither connect to the 6-pin header. The MEGA connects the SPI through pins 50-53. With the MEGA, you can use GPS for setting the time; at my location, GPS is hard to pick up, which is why I want to try WiFi.

The shields are sold on E-Bay from seller GRA & AFCH, who are in Ukraine (the first one I ordered shipped the day before the Russian invasion, the other three since the invasion).

There are other Nixie Tube Clock shields from other sellers, though I have not been to impressed by them.

The "advertising" for the UNO R4 states that the R4 will be hardware, electrically, and pin-out compatible with the R3; I hope that will be true, but, I'm too old to hold my breath.

In any case, the end of May is almost here.

You're getting into a level of programming that is above my skill/knowledge level; I prefer to keep things simple and straight forward.

In any case, it is clear the UNO WiFi R2 will not work with the shields I want to use it on.

That explains it. Except for removing the 6-pin header and soldering wires to the relevant pins (50..53) on the shield i am out of options.

The ATmega4809 can "move" the SPI port to one of three sets of pins. The default it the ICSP connector.
In theory, you should be able to define SPI1 on the 13,12,11 port by including code like:

  SPIClass SPI1 (12,  13,  11,  10,  PORTMUX_SPI0_ALT2_gc);

But I don't know whether it's been done, or whether it actually works.

(Don't try to use "SPI" after defining SPI1. There is only one SPI hardware instance, and the code doesn't know how to switch between multiple pinouts on the fly.)