ESP32 GPIO function configuration via configuration registers.

Ciro Bruno
Posts: 4
Joined: Sun Nov 28, 2021 4:56 pm

ESP32 GPIO function configuration via configuration registers.

Postby Ciro Bruno » Sun Nov 28, 2021 8:43 pm

Hello all

I've been using ESP32 for a couple of years, mostly through Arduino IDE. Since July I've been using exclusively VSCode + PlatformIO with Arduino framework. My reason for changing has been the interruption of support to SPIFFS in the latest Arduino IDE versions.

Nevertheless, now I'm facing difficulties for setting up GPIO 12 and 13 as INPUT_PULLUP in a ESP32-Pico-D4. I've been using

Code: Select all

pinMode( 12, INPUT_PULLUP);
, but this always return 0 (false), as well as trying to set it as INPUT or INPUT_PULLDOWN. Browsing some discussions in the internet I found out that the default Arduino framework version used by VSCode is outdated and has issues regarding some GPIO pins configuration.

So, I'd like to use the safest solution for this issue, that is configuring these GPIOs directly through configuration registers.

I've been reading chapter 5 of esp32_technical_reference_manual_en.pdf, but I didn't understand what to do. Maybe I need to understand better the microprocessor's architecture itself.

Anyway, I'd like to count on your help for:

item 1) setting up GPIO12 and GPIO13 as inputs with pullup, through writing on configuration registers;
item 2) understanding better how attribute functions to GPIO pads.

I'd like to start by item 1, making GPIO 12 and 13 behave as INPUT_PULLUP by writing on the proper configuration registers. Then, I'd like to play with other basic IO functions, like INPUT_PULLDOWN, INPUT and OUTPUT.

Later (item 2, I'd like to go through an overview of the GPIOs related registers, from a single GPIO pad toward a specific embedded function.

Starting from Figure 7 ("IO_MUX, RTC IO_MUX and GPIO Matrix Overview") on page 47, I'd like to understand where I should find the simple digital IOs, such as those accessible through "digitalRead" or "digitalWrite".
2.1) Are these ones are considered as "peripherals" or not? I can't identify them in the diagram.
2.2) Should they be treated attached directly to IO_MUX or via GPIO Matrix?
2.3) This Figure also shows "34 GPIOs" between "GPIO Matrix" and "IO_MUX". Isn't 34 the same number of GPIO pads? Is it a coincidence or is this label ("34 GPIOs") misplaced in the diagram?

Image

Thank you.
Best regards,
Ciro.
Attachments
Figure 7.png
Figure 7.png (43.97 KiB) Viewed 10329 times
Ciro Bruno
Process Analytics Specialist
Automation Engineer
RJ Brazil

boarchuz
Posts: 605
Joined: Tue Aug 21, 2018 5:28 am

Re: ESP32 GPIO function configuration via configuration registers.

Postby boarchuz » Mon Nov 29, 2021 6:32 am

Ciro Bruno wrote:
Sun Nov 28, 2021 8:43 pm
I've been using

Code: Select all

pinMode( 12, INPUT_PULLUP);
, but this always return 0 (false)
pinMode is void:
https://github.com/espressif/arduino-es ... gpio.h#L88
Do you mean that reading the pin level (ie. with digitalRead(12)) afterwards always returns 0?

Check your particular board's schematic to ensure 12 isn't used for something else, disconnect any external modules/LEDs/resistors/etc, and check the voltage on 12 with your multimeter. Do the same with a different pin (eg. 25 or 32).

Ciro Bruno
Posts: 4
Joined: Sun Nov 28, 2021 4:56 pm

Re: ESP32 GPIO function configuration via configuration registers.

Postby Ciro Bruno » Wed Dec 01, 2021 10:10 pm

Hi

Thank you for your attention

Indeed I've already checked all electronic signals, comparing GPIOs 12 and 13 to GPIO25.

Configuring all them as INPUT_PULLUP, GPIO25 holds close to 3.3v, while GPIO 12 and 13 keep around 0.3v.

Keeping them loose and reading them with "digitalRead()", GPIO25 keeps boolean 1 state, while GPIOs 12 and 13 never leave boolean 0.

When grounding them, one at once, GPIO25 returns boolean 0, as expected.

Reading GPIO with "touchRead()", GPIOs 12 and 13 show values between 22 and 48 when loose, falling to 0 when grounded. This is the only life signal these pins show.

All this happens when compiling and flashing with VSCode.

When compile and flashing with Arduino IDE 2.0.0, these pins work perfectly as expected.

So, I guess there should be no doubt about hardware integrity. That's why I'm looking for solving that through configuration registers.

Regards,
Ciro Bruno
Process Analytics Specialist
Automation Engineer
RJ Brazil

Ciro Bruno
Posts: 4
Joined: Sun Nov 28, 2021 4:56 pm

Re: ESP32 GPIO function configuration via configuration registers.

Postby Ciro Bruno » Sun Dec 05, 2021 9:06 pm

Again, trying to find out how to configure digital inputs and output through ports registers, I've been trying to apply "pinMode" commands to three different GPIOs and check its effect over some registers. But regardless the pin mode selected, it seems I'm watching the wrong registers.

The code I've been using is:

Code: Select all

uint8_t fase = 0;
  #define output          0
  #define input           1
  #define input_pulldown  2
  #define input_pullup    3

void print_reg(void)
{
  Serial.print("\nGPIO_IN_REG : 0b");       Serial.print(GPIO_IN_REG, BIN);
  Serial.print("\tGPIO_ENABLE_REG : 0b");   Serial.print(GPIO_ENABLE_REG, BIN);
  Serial.print("\tIO_MUX_GPIO25_REG : 0b"); Serial.print(IO_MUX_GPIO25_REG, BIN);
  Serial.print("\tIO_MUX_GPIO12_REG : 0b"); Serial.print(IO_MUX_GPIO12_REG, BIN);
  Serial.print("\tIO_MUX_GPIO13_REG : 0b"); Serial.print(IO_MUX_GPIO13_REG, BIN);
}

void setup (void)
{
  Serial.begin(115200);
  delay(500);
  Serial.print("Configuração inicial:");
  print_reg();
}

void loop (void)
{
  switch (fase) {
    case output:
      pinMode(25, OUTPUT);  pinMode(12, OUTPUT);  pinMode(13, OUTPUT);
      Serial.print("\nOUTPUT:");
      break;
     case input:
      pinMode(25, INPUT);   pinMode(12, INPUT);   pinMode(13, INPUT);
      Serial.print("\nINPUT:");
      break;
     case input_pulldown:
      pinMode(25, INPUT_PULLDOWN);  pinMode(12, INPUT_PULLDOWN);  pinMode(13, INPUT_PULLDOWN);
      Serial.print("\nINPUT_PULLDOWN:");
      break;
     case input_pullup:
      pinMode(25, INPUT_PULLUP);    pinMode(12, INPUT_PULLUP);    pinMode(13, INPUT_PULLUP);
      Serial.print("\nINPUT_PULLUP:");
      break;
    default: break;
  }
  
  delay(1000);

  print_reg();

  if (++fase > 3) fase = 0;
}
And the results I've been cyclically obtaining are:

Code: Select all

OUTPUT:
GPIO_IN_REG : 0b111111111101000100000000111100	GPIO_ENABLE_REG : 0b111111111101000100000000100000	IO_MUX_GPIO25_REG : 0b111111111101001001000000100100	IO_MUX_GPIO12_REG :0b111111111101001001000000110100	IO_MUX_GPIO13_REG : 0b111111111101001001000000111000
INPUT:
GPIO_IN_REG : 0b111111111101000100000000111100	GPIO_ENABLE_REG : 0b111111111101000100000000100000	IO_MUX_GPIO25_REG : 0b111111111101001001000000100100	IO_MUX_GPIO12_REG : 0b111111111101001001000000110100	IO_MUX_GPIO13_REG : 0b111111111101001001000000111000
INPUT_PULLDOWN:
GPIO_IN_REG : 0b111111111101000100000000111100	GPIO_ENABLE_REG : 0b111111111101000100000000100000	IO_MUX_GPIO25_REG : 0b111111111101001001000000100100	IO_MUX_GPIO12_REG : 0b111111111101001001000000110100	IO_MUX_GPIO13_REG : 0b111111111101001001000000111000
INPUT_PULLUP:
GPIO_IN_REG : 0b111111111101000100000000111100	GPIO_ENABLE_REG : 0b111111111101000100000000100000	IO_MUX_GPIO25_REG : 0b111111111101001001000000100100	IO_MUX_GPIO12_REG : 0b111111111101001001000000110100	IO_MUX_GPIO13_REG : 0b111111111101001001000000111000
This code has run in Arduino 2.0.0-beta.7

Given these results, which might be the registers affected by "pinMode" command?

Please help.
Thank you.
Regards,
Ciro.
Ciro Bruno
Process Analytics Specialist
Automation Engineer
RJ Brazil

Ciro Bruno
Posts: 4
Joined: Sun Nov 28, 2021 4:56 pm

Re: ESP32 GPIO function configuration via configuration registers.

Postby Ciro Bruno » Tue Dec 14, 2021 2:27 pm

The matter here it that the compiler doesn’t allow the register to be read or written as a variable.


ciro_bruno:
Serial.print(GPIO_IN_REG, BIN);
So, doing so I can get just the register’s address itself (0b111111111101000100000000111100).

As far as I can remember, in Arduino environment it is/was possible to read and write directly on the registers through their mnemonics.

Anyway, I guess I’ve got to find out another way.

I’ve been thinking of doing so via pointers. I’ve been trying, but I haven’t been able to attribute the register’s address (a constant) to the pointer . Neither can read the address the pointer points to.

Code: Select all

  uint32_t conteudo;
  uint32_t *reg_PTN;

  reg_PTN = (uint32_t) GPIO_ENABLE_REG; //  #define GPIO_ENABLE_REG (DR_REG_GPIO_BASE + 0x0020) | #define DR_REG_GPIO_BASE 0x3ff44000
  conteudo = *reg_PTN;

  Serial.print("\nGPIO_ENABLE_REG = 0x"); Serial.print( reg_PTN, HEX);
  Serial.print("\tConteudo = 0b"); Serial.print (*reg_PTN, BIN);
The error messages are:

Code: Select all

src\main.cpp:8:11: error: invalid conversion from 'uint32_t {aka unsigned int}' to 'uint32_t* {aka unsigned int*}' [-fpermissive]
   reg_PTN = (uint32_t) GPIO_ENABLE_REG; //  #define GPIO_ENABLE_REG (DR_REG_GPIO_BASE + 0x0020) | #define DR_REG_GPIO_BASE 0x3ff44000   
           ^
src\main.cpp:11:69: error: no matching function for call to 'print(uint32_t*&, int)'
   Serial.print("\nGPIO_ENABLE_REG = 0x"); Serial.print( reg_PTN, HEX);
                                                                     ^
So, how could I give this pointer the register’s address?

Thank you.
Regards,
Ciro.
Ciro Bruno
Process Analytics Specialist
Automation Engineer
RJ Brazil

Who is online

Users browsing this forum: No registered users and 66 guests