Skip to content
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

Reading GPIO16 on power up #8783

Closed
joehui opened this issue Jan 3, 2023 · 6 comments
Closed

Reading GPIO16 on power up #8783

joehui opened this issue Jan 3, 2023 · 6 comments

Comments

@joehui
Copy link

joehui commented Jan 3, 2023

Basic Infos

We are working on something that requires me to detect the state of GPIO16 inside user_rf_pre_init() - more specifically, in RF_PRE_INIT() in Arduino IDE.

Platform

  • Hardware: ESP-12F
  • Core Version: 3.0.2
  • Development Env: Arduino IDE / NONOS_SDK
  • Operating System: MacOS

Settings in IDE

  • Module: Nodemcu 1.0 (ESP-12E Module)
  • Flash Size: 4MB
  • lwip Variant: v2 Lower Memory
  • CPU Frequency: 160MHz
  • Upload Using: SERIAL
  • Upload Speed: 115200

Problem Description

We tried the following code, but it always returns me the same value:

RF_PRE_INIT()
{
  system_phy_set_powerup_option(2);
 
  GPIO_DIS_OUTPUT(GPIO_ID_PIN(16));
  int value = GPIO_INPUT_GET(GPIO_ID_PIN(16));
  GPIO_OUTPUT_SET(GPIO_ID_PIN(2), value );        //  Set LED based on state of Pin 16
}

We tried various APIs in NONOS_SDK, but none worked. For other GPIOs, we were able to do something like:

  PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12);     
      OR
  PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14);

before we setup the GPIO. But for GPIO16, there is no equivalent.

We understand that GPIO16 is part of the RTC system and is handled differently but we cannot find the appropriate example or documentation on reading GPIO16.

Help would be greatly appreciated!

Joseph

@mcspr
Copy link
Collaborator

mcspr commented Jan 3, 2023

GPIO_DIS_OUTPUT(GPIO_ID_PIN(16));

pinMode?

We understand that GPIO16 is part of the RTC system and is handled differently but we cannot find the appropriate example or documentation on reading GPIO16.

Just use Arduino API?

GPIO16 is a separate thing, yes, see our pinMode and digital{Read,Write} implementations on top of the register macros
https://github.com/esp8266/Arduino/blob/master/cores/esp8266/core_esp8266_wiring_digital.cpp
(...which is probably due for a rewrite to make it more readable. atm, works best with some kind of code completion / lsp server that expands preprocessor right in the editor...)

Otherwise, you'd have to use SDK headers as reference for GPIO access
https://github.com/esp8266/Arduino/blob/da6ec83b5fdbd5b02f04cf143dcf8e158a8cfd36/tools/sdk/include/eagle_soc.h

Also see espressif's RTOS esp8266 component for a much more coherent header and register<->struct API
https://github.com/espressif/ESP8266_RTOS_SDK/blob/master/components/esp8266/include/esp8266/gpio_register.h
https://github.com/espressif/ESP8266_RTOS_SDK/blob/master/components/esp8266/include/esp8266/gpio_struct.h

@dok-net
Copy link
Contributor

dok-net commented Mar 12, 2023

Should #7979 get merged:

RF_PRE_INIT()
{
    system_phy_set_powerup_option(2);
    // ...
}

The right thing to do will be to overwrite the weak symbol __get_rf_powerup_mode() and return 2, then remove the line system_phy_set_powerup_option(2);

@dok-net
Copy link
Contributor

dok-net commented Mar 12, 2023

Let's drill down deeper, though.
First, an MCVE that will actually compile:

// This Arduino code is specific to the ESP8266
#include "user_interface.h"

RF_PRE_INIT()
{
    system_phy_set_powerup_option(2);
    // ...
}

void setup()
{
}
void loop()
{
}

@joehui Did you take into consideration the changes in release 3.0.0, since which WiFi is disabled by default? According to https://www.espressif.com/sites/default/files/documentation/2c-esp8266_non_os_sdk_api_reference_en.pdf, is the parameter value 2 really what you want?

Fast-forward to #7979, system_phy_set_powerup_option(2) is default anyway, which only calibrates VDD33 because WiFi is assumed to be disabled. So there's no need to even overwrite __get_rf_powerup_mode() at all. Should WiFi be required, I don't know that it is safe to elide the calibration of TX power (system_phy_set_powerup_option 0, 1, or 3).

@joehui
Copy link
Author

joehui commented Mar 13, 2023 via email

@TD-er
Copy link
Contributor

TD-er commented Mar 13, 2023

@joehui
Can you please edit your post to add 3 backticks wrapping the code?
I got the impression some code formatting got lost as it seems like you commented out the function declarations.

@joehui
Copy link
Author

joehui commented Mar 13, 2023

Sorry, here's the code again.

//  GPIO16 functions
void ICACHE_FLASH_ATTR gpio16_output_conf(void)
{
    WRITE_PERI_REG(PAD_XPD_DCDC_CONF,
                   (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | (uint32)0x1);   // mux configuration for XPD_DCDC to output rtc_gpio0
    WRITE_PERI_REG(RTC_GPIO_CONF,
                   (READ_PERI_REG(RTC_GPIO_CONF) & (uint32)0xfffffffe) | (uint32)0x0);  //mux configuration for out enable
    WRITE_PERI_REG(RTC_GPIO_ENABLE,
                   (READ_PERI_REG(RTC_GPIO_ENABLE) & (uint32)0xfffffffe) | (uint32)0x1);  //out enable
}

void ICACHE_FLASH_ATTR gpio16_output_set(uint8 value)
{
    WRITE_PERI_REG(RTC_GPIO_OUT,
                   (READ_PERI_REG(RTC_GPIO_OUT) & (uint32)0xfffffffe) | (uint32)(value & 1));
}

void ICACHE_FLASH_ATTR gpio16_input_conf(void)
{
    WRITE_PERI_REG(PAD_XPD_DCDC_CONF,
                   (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | (uint32)0x1);  // mux configuration for XPD_DCDC and rtc_gpio0 connection
    WRITE_PERI_REG(RTC_GPIO_CONF,
                   (READ_PERI_REG(RTC_GPIO_CONF) & (uint32)0xfffffffe) | (uint32)0x0);  //mux configuration for out enable
    WRITE_PERI_REG(RTC_GPIO_ENABLE,
                   READ_PERI_REG(RTC_GPIO_ENABLE) & (uint32)0xfffffffe);  //out disable
}

uint8 ICACHE_FLASH_ATTR gpio16_input_get(void)
{
    return (uint8)(READ_PERI_REG(RTC_GPIO_IN_DATA) & 1);
}
//  GPIO16 functions End



// Reduce powerup current base on whether GPIO16 is pressed on power up
RF_PRE_INIT()
{
  gpio16_input_conf();                //config GPIO16 to input
  if (0==gpio16_input_get())          //if setup button is left alone (not pressed)
    system_phy_set_powerup_option(2); //disable RF calibration (else go ahead with calibration)
}

@mcspr mcspr closed this as completed Mar 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants