Skip to content

Core attempts to use GPIO_OUT1_REG and GPIO_IN1_REG on chips that don't have it #5378

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
maxgerhardt opened this issue Jul 12, 2021 · 3 comments · Fixed by #5402
Closed

Core attempts to use GPIO_OUT1_REG and GPIO_IN1_REG on chips that don't have it #5378

maxgerhardt opened this issue Jul 12, 2021 · 3 comments · Fixed by #5402
Assignees
Labels
Chip: ESP32-C3 Issue is related to support of ESP32-C3 Chip

Comments

@maxgerhardt
Copy link
Contributor

maxgerhardt commented Jul 12, 2021

Hardware:

Board: ESP32C3
Core Installation version: latest git (cbcba53)
IDE name: Platform.io
Flash Frequency: 80Mhz
PSRAM enabled: no
Upload Speed: 115200
Computer OS: Windows 10 x64

Description:

I am trying to compile an simple test sketch for the Adafruit SSD1306 library for an ESP32C3 board configuration.

I am using PlatformIO to pull the latest PlatformIO core version, then change up some board compilation info to make it compile for the ESP32C3 variant. Compilation is successfull for simple sketches, (e.g., blinky and Serial.println() stuff).

The Adafruit SSD1306 library, or more specificically its Adafruit Bus IO dependency, makes use of the portOutputRegister and portInputRegister macros for faster I/O access on ESP32 platforms.

See here

#elif defined(ESP8266) || defined(ESP32) || defined(__SAM3X8E__) ||            \
    defined(ARDUINO_ARCH_SAMD)
typedef volatile uint32_t BusIO_PortReg;
typedef uint32_t BusIO_PortMask;
#define BUSIO_USE_FAST_PINIO

and here for usage.

The core defines thesse macros as follows

#define portOutputRegister(port) ((volatile uint32_t*)((port)?GPIO_OUT1_REG:GPIO_OUT_REG))
#define portInputRegister(port) ((volatile uint32_t*)((port)?GPIO_IN1_REG:GPIO_IN_REG))
#define portModeRegister(port) ((volatile uint32_t*)((port)?GPIO_ENABLE1_REG:GPIO_ENABLE_REG))

But the GPIO_OUT1_REG and GPIO_IN1_REG are referenced here, that, if one does a code occurance search, is only defined for ESP32S2 chips.

#define GPIO_OUT1_REG (DR_REG_GPIO_BASE + 0x10)

So it does not exist for the ESP32C3 chip I am compiling for. Yet, the core references those in the macros above for all ESP32 chip variants.

This leads to an immediate compilation failure of the library.

In file included from .pio/libdeps/esp32c3/Adafruit BusIO/Adafruit_SPIDevice.cpp:2:
.pio/libdeps/esp32c3/Adafruit BusIO/Adafruit_SPIDevice.cpp: In constructor 'Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t, int8_t, int8_t, int8_t, uint32_t, BitOrder, uint8_t)':
C:/Users/Max/.platformio/packages/framework-arduinoespressif32/cores/esp32/Arduino.h:106:66: error: 'GPIO_OUT1_REG' was not declared in this scope
 #define portOutputRegister(port)    ((volatile uint32_t*)((port)?GPIO_OUT1_REG:GPIO_OUT_REG))
                                                                  ^~~~~~~~~~~~~
.pio/libdeps/esp32c3/Adafruit BusIO/Adafruit_SPIDevice.cpp:54:29: note: in expansion of macro 'portOutputRegister'
   csPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(cspin));
                             ^~~~~~~~~~~~~~~~~~
C:/Users/Max/.platformio/packages/framework-arduinoespressif32/cores/esp32/Arduino.h:106:66: note: suggested alternative: 'GPIO_OUT_REG'
 #define portOutputRegister(port)    ((volatile uint32_t*)((port)?GPIO_OUT1_REG:GPIO_OUT_REG))
                                                                  ^~~~~~~~~~~~~
.pio/libdeps/esp32c3/Adafruit BusIO/Adafruit_SPIDevice.cpp:54:29: note: in expansion of macro 'portOutputRegister'
   csPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(cspin));
                             ^~~~~~~~~~~~~~~~~~
C:/Users/Max/.platformio/packages/framework-arduinoespressif32/cores/esp32/Arduino.h:107:66: error: 'GPIO_IN1_REG' was not declared in this scope
 #define portInputRegister(port)     ((volatile uint32_t*)((port)?GPIO_IN1_REG:GPIO_IN_REG))
                                                                  ^~~~~~~~~~~~
.pio/libdeps/esp32c3/Adafruit BusIO/Adafruit_SPIDevice.cpp:61:33: note: in expansion of macro 'portInputRegister'
     misoPort = (BusIO_PortReg *)portInputRegister(digitalPinToPort(misopin));
                                 ^~~~~~~~~~~~~~~~~
C:/Users/Max/.platformio/packages/framework-arduinoespressif32/cores/esp32/Arduino.h:107:66: note: suggested alternative: 'GPIO_IN_REG'
 #define portInputRegister(port)     ((volatile uint32_t*)((port)?GPIO_IN1_REG:GPIO_IN_REG))
                                                                  ^~~~~~~~~~~~
.pio/libdeps/esp32c3/Adafruit BusIO/Adafruit_SPIDevice.cpp:61:33: note: in expansion of macro 'portInputRegister'
     misoPort = (BusIO_PortReg *)portInputRegister(digitalPinToPort(misopin));
                                 ^~~~~~~~~~~~~~~~~

I think the core should give define idfferent portXRegister() macros for the different chip variants to fix this bug.

Commenting out the #define BUSIO_USE_FAST_PINIO macro to not make use of those macros leads to an immediate compilation successs.

Checking size .pio\build\esp32c3\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [          ]   3.1% (used 10276 bytes from 327680 bytes)
Flash: [=         ]   7.7% (used 243722 bytes from 3145728 bytes)
Building .pio\build\esp32c3\firmware.bin
esptool.py v3.1
Merged 1 ELF section
=========== [SUCCESS] Took 9.31 seconds ===========

Sketch: (leave the backquotes for code formatting)

#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup(){
  Serial.begin(115200);
  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
  display.display();
}
void loop() {}

platformio.ini

[env:esp32c3]
platform = espressif32
platform_packages =
        toolchain-riscv-esp
        framework-arduinoespressif32@https://github.com/espressif/arduino-esp32.git#master
        platformio/tool-esptoolpy @ ~1.30100
framework = arduino
; take usual esp32dev board and modify meta-info
; to make it a ESP32C3 board.
board = esp32dev
board_build.mcu = esp32c3
board_build.partitions = huge_app.csv
board_build.variant = esp32c3
board_build.f_cpu = 160000000L
board_build.f_flash = 80000000L
board_build.flash_mode = qio
board_build.arduino.ldscript = esp32c3_out.ld
; remove old build flags
build_unflags =
  -DARDUINO_ESP32_DEV
  -DARDUINO_VARIANT="esp32"
; inject new ones
; uncommont Serial macros below if serial is not working..
build_flags =
  -DARDUINO_ESP32C3_DEV
  -DARDUINO_VARIANT="esp32c3"
;  -DARDUINO_SERIAL_PORT=1
;  -DBOARD_HAS_PSRAM
; -DCORE_DEBUG_LEVEL=5
lib_deps =
     adafruit/Adafruit SSD1306 @ ^2.4.6
     adafruit/Adafruit GFX Library @ ^1.10.10
     adafruit/Adafruit BusIO @ ^1.8.2

Debug Messages:

None relevant since compilation failure.

@maxgerhardt
Copy link
Contributor Author

maxgerhardt commented Jul 12, 2021

In hindsight this seems weird. I remember the 'normal' ESP32 chip having two sets of OUT etc. registers too, for I/Os 0-31 and 32-39 respectively. Per manual page 62

grafik

But yet these register definitions don't show up when searching for them here. Weird. I'd love for someone with more technical knownedge on the different ESP32 to weigh in here.

@me-no-dev
Copy link
Member

Are you looking for the upper GPIO OUT register for C3? Since C3 has less than 32 GPIOs defined, it has only one GPIO_OUT_REG (0x0004) or are you looking on how we use those in Arduino? If so, we use them through structs of register addresses, rather than using direct register addresses

@maxgerhardt
Copy link
Contributor Author

maxgerhardt commented Jul 12, 2021

The primary issue here is the compilation failure. I don't want to access the registers myself, I'm concerned that a library using the portOutputRegister() and related from this core does not compile for the ESP32C3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Chip: ESP32-C3 Issue is related to support of ESP32-C3 Chip
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants