Arduino-esp32: Unable to Change SPI SCLK in SPI.cpp when using different IDEs (Component vs. PlatformIO)

Created on 9 Oct 2017  路  15Comments  路  Source: espressif/arduino-esp32

Hardware:

Board: ESP32 DevKit-C
Core Installation/update date: Latest
IDE name: Multiple (ESP-IDF Arduino Component vs. Platform IO)
Flash Frequency: 40Mhz
Upload Speed: 115200

Summary:

I've come across an interesting roadblock. I am not able to change the SPI SLCK frequency in the SPI.cpp library when using arduino-esp32 as a ESP-IDF component. When I use PlatformIO with identical settings, I am able to change the SPI SLKC frequency. It has nothing to do with the U8g2 library as I have tried to hardcode the SPI.cpp frequency values without success.

Description

Arduino-esp32 dictates 4 ways of using the Arduino API with ESP-IDF in the instructions/readme.

Method 1 - Using Arduino API as ESP-IDF Component [This doesn't work]

One of those ways is to use Arduino API as an ESP-IDF component as described here. I managed to add Arduino API to ESP-IDF using this method. Next, I've added a component.mk file to @olikraus's U8g2_Arduino fork.

Component.mk has the following options to add source directors and include files:

COMPONENT_SRCDIRS:=src src/clib
COMPONENT_ADD_INCLUDEDIRS:=src src/clib

Now, U8g2 is a component of ESP-IDF.

Everything works except There is one problem. Usually, I am able to edit the SPI frequency in the u8x2_d_ssd1306_128x64_noname.c,

/* sck_clock_hz = */ 10000000UL,

however, no matter what frequency I set and upload to ESP32, I always get 8MHz as the clock freq. I've validated it using a scope.

1

I've hardcoded the SPI freq to 10 MHz in the arduino-esp32 SPI.c file and it still doesn't work:

void SPIClass::beginTransaction(SPISettings settings)
{
    //check if last freq changed
    uint32_t cdiv = spiGetClockDiv(_spi);
    if(_freq != settings._clock || _div != cdiv) {
        // _freq = settings._clock;
        _freq = 10000000UL; // Temporarily hardcoding it for debug purpose. No matter what freq I set here, the default is always 8 MHz.
        _div = spiFrequencyToClockDiv(_freq);
    }
    spiTransaction(_spi, _div, settings._dataMode, settings._bitOrder);
    _inTransaction = true;
}

So I tried to use arduino-esp32 using PlatformIO. This problem does not happen when I use Platform IO and downloading latest U8g2 library + arduino-esp32 platform.

Method 2 - Using PlatformIO [This works]

So, I tried the same test as above and I changed the u8x8_d_ssd1306_128x64_noname.c LINE 235 to use 10 MHz as the clock frequency.

/* sck_clock_hz = */ 10000000UL,

This time, using Platform IO toolchain, it works! I checked it with a scope and I am getting 10 MHz as the clock frequency.

3

Scope screenshot says 9.62 MHz but it is 10 MHz when I change the horizontal scale.

I am pretty sure I am missing something obvious here.

Any ideas on what must be going on?

Sketch:

#include <Arduino.h>
#include <U8g2lib.h>
#include <SPI.h>
#include <Wire.h>

U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI display1(U8G2_R0, /* CS = */ 16, /* DC = */  17, /* RS = */  4);

void setup(void) {
    display1.begin();
    display1.setFont(SPINZERO); // Font file not shown here
    display1.setFontPosCenter();
}

void loop(void) {

    static unsigned long thisMicros = 0;
    static unsigned long lastMicros = 0;

    for (int i = 0; i < 60; i++) {
        display1.clearBuffer();
        display1.setCursor(64,20);
        display1.print("FPS TEST!");

        // tpf = Time Per Frame
        unsigned long tpf = thisMicros - lastMicros;
        display1.setCursor(64,32);
        display1.print(tpf);
        display1.setCursor(88,32);
        display1.print("yS/F");

        // fps = Frame Per Second
        unsigned long fps;
        if (tpf ==0) {
            fps = 0;
        } else {
            fps = 1000000/tpf;
        }
        display1.setCursor(64,44);
        display1.print(fps);
        display1.setCursor(88,44);
        display1.print("FPS");

        display1.sendBuffer();

        lastMicros = thisMicros;
        thisMicros = micros();
    }
}

All 15 comments

try make clean and make again... I have no clue really :) using as IDF component here as well and have no issues with SPI frequency at all. I bet it's something really stupid going on in the build.

@me-no-dev I have tried make clean so many times today, I think I am going to dream about it tonight :rofl:

Let me try to install this on a completely new linux VM and get back to you.

Update:
I set the clock in the https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-spi.c#L708 without success. No matter what freq I set here, nothing changes on pin 18.

//spi->dev->clock.val = clockDiv; // Original
spi->dev->clock.val = spiFrequencyToClockDiv(10000000UL); // Temporary hardcoding freq

I am able to reproduce the error on a new Ubuntu 16.04 VM while following exact instructions of setting up the ESP-IDF and arduino-esp32 as a component from the Wiki.

I might have found the issue ;) https://github.com/neilpanchal/U8g2_Arduino/blob/master/src/U8x8lib.cpp#L420
If ARDUINO is not defined as version, transactions are not used.

Try compiling under ArduinoIDE, if it works, then the lib is needs some updates to get it to work

To my knowledge ARDUINO always had a version number in standard Arduino IDE. "beginTransaction" was introduced around 1.6.0. I do not know what to change here. In order to make u8g2 compatible with older versions of the original Arduino IDE, i have to check the IDE version.

yeah, but he is using IDF ;)

Can someone educate me where exactly in the whole toolchain ARDUINO is defined?
#if ARDUINO >= 10600
@me-no-dev I've ripped my hair out all day with this issue. I'm down in a couple of beers now :beer:. I'll check if the problem exists on Arduino IDE in the morning. The fact that the issue didn't happen with Platform IO build, you seem to have nailed down the root cause 馃憤

I'll add define for this in the component config and that should clear the issue :)

Please pull the latest arduino and give it another go :)

@me-no-dev Awesome.

For my education, what does the default -DARDUINO=180 mean? Is this a version number akin to 0.18?

AFAIK should be 1.8 but maybe version numbers changed at some point. Added this long long time ago :D no clear memory at which lib/IDE I was looking for inspiration

@me-no-dev Confirmed working on both original setup and the new ubuntu VM. Thank you!
@olikraus I cranked up the SPI freq to 12 MHz and getting approx 425 frames/sec on SSD1306 based oled display :sunglasses:

For my education, what does the default -DARDUINO=180 mean? Is this a version number akin to 0.18?
Actually it should be a 5 digit number. For Example IDE Version 1.8.3 is represented as 10803. I guess Version 1.6.11 should be 10611

I have not tracked down where exactly this is defined, but the value for the ARDUINO macro is defined here:
https://github.com/arduino/arduino-builder/blob/master/src/arduino.cc/arduino-builder/main.go#L151

@olikraus I cranked up the SPI freq to 12 MHz and getting approx 425 frames/sec on SSD1306 based oled display :sunglasses:

Amazing, but this is probably beyond the spec of the SSD1306

Was this page helpful?
0 / 5 - 0 ratings