@RWB, @rickkas7, it seems there is an issue with the SPI firmware on Gen3 devices where the CLK clock line will “glitch” when the SPI configuration is changed “on-the-fly”. I recall this being an issue which was fixed in Gen2 devices. The library being used is the Adafruit_SharpMem
code I had adapted to work with my Adafruit_mfGFX
library. The code is here:
The SharpMem display requires commands be sent in MSBFIRST format while display data to be sent in LSBFIRST format (!!). As such, the Adafruit_SharpMem
code has an additional SPI byte send function to send a byte in LSBFIRST order and then switch back to MSBFIRST format which is the default. The tested code moved the SPI.setBitOrder()
function calls from various locations to the sendByteLSB()
function as follows:
void Adafruit_SharpMem::sendbyteLSB(uint8_t data)
SPI.setBitOrder(LSBFIRST);
SPI.transfer(data);
SPI.setBitOrder(MSBFIRST);
}
The test code displays a set of calculated graphs on the display. Capturing the SPI data using a DSLogic LA, the first action on the display is to clear it by sending 0xFF for all display bytes.
On a Photon compiled to DeviceOS 2.0.9-rc.1, the code runs flawlessly. The captured SPI data shows the expected normal SPI pin activity (2 command bytes then data). Note the “clean” CLK
pin being active only when data is to be sent.
On the Argon, the same code and DeviceOS (only CS pin is changed), the CLK
shows pre-transfer activity, likely when SPI.setBitOrder(LSBFIRST)
is called:
The unwanted CLK
pulse causes a false bit to be clocked into the SPI receive register of the display. The outcome is what looks like “noise” on the display, as data is now corrupted.
In order to test if the SPI.setBitOrder()
call is the problem, I added code to flip the bit order (MSBFIRST to LSBFIRST) and thus remove the need for changing the SPI mode. This was done with a nibble lookup table coupled with bit shift operations. The new sendByteLSB()
function is as follows:
void Adafruit_SharpMem::sendbyteLSB(uint8_t data)
{
// Table to reverse the top and bottom nibble then swap them.
static const unsigned char lookup[16] = {
0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf, };
SPI.transfer((lookup[data&0b1111] << 4) | lookup[data>>4]);
}
With this rewritten function, the SPI CLK
line no longer glitches and the code displays the expected test graphs as expected.
I will need to let the Particle folks know about this SPI bus glitching if @rickkas7 can’t comment.