SOLVED: Recalcitrant 6 pin SPI SSD1306 0.96" OLED - SAMD21 woes

I tried to disconnect #CS pin (in red below) from GND and greenwire to it but the flexPCB via was too far back and I couldn’t get the blade in and retain access to tinned pad on the kapton. I also checked the BS mode select pins (in green below) are all connected to ground to ensure 4 wire SPI. So I’m inclined to agree with @MLXXXp that SW is the place to start looking.

Trying a “bare minimum” sketch comparison on the scope now, using just the display.begin() command in loop, every 5 seconds. Digging back into Adafruit and u8glib2 files to slow the clocks down again…

It’s already working with software SPI, so how could it be wired for I2C?

Software SPI top:

Hardware SPI below:

Well the oscilloscope gets the message, but so far sadly nothing on the OLED with HW SPI. The data is the first section of the display.begin() function from the Adafruit example.

And how does that compare to software SPI?

It doesn’t have all the pins broken out. The data pins are the same. Just depends how you initialize the data connection.

Basically the manufacturer handicapped the PCB.

Only CS is missing. It’s only needed if you want to connect more devices to the same SPI interface. I have an OLED module with the same missing CS and have never had a problem with it.

SW and HW SPI were next to each other for comparison in that message. They look reasonably similar zoomed out.

Just had a look a bit closer. (magenta trace is RESET and blue trace is D/C)


And closer still.


No, you have to hard wire the display for either SPI or I2C using the BS0-2 pins. You can’t switch modes in software (unless you have an external means of setting BS1).


Looking on your 1st posted images. I noticed while looking at the 0x00 byte, SDA is low while idle using software (easier to spot at right side of byte transfer) but it’s high with hardware. Can’t clearly see the relation to SCK though.

*idle: time between transferred bytes

What I noticed in your latest image, on software data is set before rising edge of SCK (as it should) and also kept stable on faling edge of SCK. However on hardware the data changes simultatiously with faling edge.
1 Like

@MLXXXp @Mr.Blinky here’s where I think the culprit is - permanently wired CS, just as @Mr.Blinky suggested. The HW SPI is idling the MOSI and SCK lines high. Ordinarily, the deassertion of CS would prevent the transition of SCK to idle HIGH from being read by the slave but here, the SSD1306 is listening to everything. This single bit every now and again could be throwing everything off.
Software SPI - lines idle LOW, so no erroneous clock edges:

Hardware SPI - lines idle HIGH, but idling is being treated as legitimate signalling by the SSD1306:

I will wait until I get my 7 pin OLED with CS pin broken out, rather than wasting any more time on this heinous module. Shame, as I was hoping to make some decent progress with my Ardugirl.

I was just thinking that they may be idling high because of the 10K pullup resistors on the display module. You could try a 1K pull down on SCK

Another thing you could try is configuring the pins as output and set them low before the SPI hardware is initialized
1 Like

Have you checked the hardware SPI data bit order?

on SAM3X it’s fixed and I think I had an issue with the bit order being the wrong way around. I had to flip data in software.

Spam something like 0xF2 and check on the oscilloscope which side the ‘2’ is closer to.

EDIT: Ah nevermind, I read the text but didn’t look at the pictures. Just saw the signal analyser screenshots.

EDIT2: What if you reset the OLED after initializing the hardware SPI and keeping the hardware SPI active so it doesn’t idle high?

1 Like

R.I.P. Me I was wrong :skull: @MLXXXp inherits Arduboy, Inc and all of it’s tax liabilities. May the force be with you.

Aaand we have a winner: @Mr.Blinky :trophy: :1st_place_medal: . Traced the 10k pullups to VREG and D0/D1. Removed them, tried the Adafruit example with success, so moved over to the ArduboyZ “Hello World” again and voila:

This episode has at least one silver lining, which is that I hadn’t realised @MLXXXp’s ArduboyZ had done lots of the bare minimum conversion for SAMD21 which is needed. That will be exceptionally useful when running through Arduboy2 and trying to get a minimal port going.


What is ArduboyZ? I gather its a port for other processors or something??

Yes, a “minimal” port for Arduino Zero of the original Arduboy library. There are fewer optimisations, which is why I call it minimal. But the SAMD21 chip on the Zero is more powerful/faster so optimisations are less important. My understanding is that it would be more fruitful for my DIY Arduboy based on the SAMD21G18A, which I often refer to as the Ardugirl, to port using the Arduboy2 library so that’s what I’m going to work on now that I have the OLED working using the ArduboyZ library.

1 Like

Right … I have since found a link to it > My Arduino Zero based system - The next generation Arduboy?

I wasn’t aware that it existed.

1 Like

@MLXXXp linked to it when he kindly provided its pinout for me to use as a guide in my own build.


FWIW, my 0.96" OLED module with CS missing doesn’t have pullups. It only has series resistors (poorly) intended to allow 5V levels on the inputs.


1 Like

Mine was a very rare layout, by the looks of things. I couldn’t find an identical image on the web, and none of the module schematics matched it :roll_eyes: