Issue with Artemis ATP and Adafruit EPD library

I understand that expecting a library to just work for a product line it doesn’t support is wishful thinking, but I am stumped by the specific error I am getting. When I try to compile a sketch for the Artemis ATP(or any other Artemis product but the ATP is what I have) that is only:

#include "Adafruit_EPD.h"


void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

I get errors for many variant and library files all pointing to

C:\Users\me\AppData\Local\Arduino15\packages\SparkFun\hardware\apollo3\1.2.1\variants\redboard_artemis_atp/config/variant.h:82:14: error: expected ‘,’ or ‘…’ before numeric constant

#define MISO 6

I want to have these two play nice and have been going through them trying to fully understand the library but I don’t understand why only the MISO declaration is causing problems. Is there a fundamental difference in the way the Artemis functions for SPI? Any direction is helpful at this point.

I believe the issue is that library is dependent on the Adafruit_BusIO library [https://github.com/adafruit/Adafruit_BusIO] for the SPI communication and the Artemis module isn’t predefined here: https://github.com/adafruit/Adafruit_Bu … PIDevice.h

I’m able to get it almost working perfectly with no changes using Arduino 1.8.12 and the newest versions of the EPD library but it seems to be failing in an Artemis-specific place. After declaring an SPIClass and then attempting to transfer using that class it just…doesn’t. I can post more of the code but the problem abridged is:

SPIClass *_spi = NULL;    // From Adafruit_MCPSRAM.h
csLow();                                   // From Adafruit_MCPSRAM.cpp
(void)_spi->transfer(0xFF);	// From Adafruit_MCPSRAM.cpp

I’ve been putting a while (!Serial.available()) {} before the csLow() so I can capture the SPI transaction on an oscilloscope and there is no clock activity (SCK) at all. I have tried to work backwards through the SPI libraries for the apollo3 but I have no familiarity with mbed and am quite lost.

I wrote a simple sketch that should draw a horizontal line spanning the top of the display, and prints the coordinates it will draw pixels to right before drawing - which are correct. What it does instead is shown here

. Because of that I’m thinking the Artemis is communicating with the display fine but has issues with the sram, either in startup or when reading data.

Any help with the mbed SPI is greatly appreciated.

The code does not make sense to me. Do you somewhere do calls like :

  • MbedSPI mySPI(mySDI, mySDO, myCLK); // declare the custom MbedSPI object mySPI ?

  • mySPI.begin();

  • and for transfer :

— spi.beginTransaction(SPISettings(SPI_FREQ, SPI_ORDER, SPI_MODE));

— rx = spi.transfer(tx);

— spi.endTransaction();

No, that’s the main issue. That setup is pretty straightforward and intuitive; the way it is done in the library is through an SPIClass *spi = NULL call. Tracking it to the apollo3 SPI src I can see this line in the SPI.cpp at line 20:

dev->write((const char*)&tx, 1, (char*)&ret, 1);

dev is initialized as ```
mbed::SPI* dev

I have verified the code gets to this dev->write as expected with correct data. Printing the _mosi, _miso, and _sck all return the correct values for hardware SPI. Up until that write command I would expect it to work normally.

Where is dev->write defined? What file holds this elusive write command?

with SPIClass *spi = NULL all you do is create an instance of SPI. SPI miso, mosi and CLK are defined in SPI.cpp at line 87 and hence you get the right pin numbers : ```
arduino::MbedSPI SPI(VARIANT_SPI_SDI, VARIANT_SPI_SDO, VARIANT_SPI_CLK);


Now you need to "connect" the SPI-instance instance to Mbed-SPI driver. That is handled with begin() where the pointer (dev) to the driver is initialized. The MBED driver is located in cores/mbed-os/drivers/source/SPI.cpp. It is here where you will find write(). Without doing a begin() call it will not work. Hence I wrote : - mySPI.begin();

At beginTransaction(), it will check whether you have an dev-pointer, if not it will call begin(). It will then also check whether the current SPI settings are the one you want, else it will make changes. Hence I wrote : 

--- spi.beginTransaction(SPISettings(SPI_FREQ, SPI_ORDER, SPI_MODE));

--- rx = spi.transfer(tx);

--- spi.endTransaction();

P.s. Any changes to the MBED SPI driver are not taken into account. MBED is provided as a pre-compiled library to reduce compile time.

In the Adafruit_MCPSRAM.cpp there is a call to begin the spi at line 65:

if (hwSPI)  {
_spi->begin();

And any call to begin() in SPI.cpp initializes as

dev = new mbed::SPI(_mosi, _miso, _sck);

I can confirm that it goes into the begin() and creates the new dev there. I’ve also confirmed that the spi object for the EPD spi transactions spi_dev also goes into the begin - obviously it should but I’m just making sure.

I realize I could make an entirely new mbed SPI object for this MCPSRAM part, but the thing that is breaking my brain is that there is no reason it shouldn’t work. It’s following all the rules of the SPI and doing it the same as the EPD spi setup and getting different results. The only difference is that the EPD uses a library called Adafruit_SPIDevice which is just a wrapper for doing the exact same things that the MCPSRAM library is doing.

What if you try older releases of the Adafruit EPD (V2.4.1) & GFX (V1.7.3) libraries?