mirror of
https://github.com/skot/ESP-Miner.git
synced 2025-03-17 13:22:53 +01:00
added i2c-test branch
This commit is contained in:
parent
6db109a29c
commit
c6448abcd8
11
.gitignore
vendored
Normal file
11
.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
# Configuration files
|
||||
sdkconfig
|
||||
sdkconfig.old
|
||||
|
||||
# Production folder
|
||||
build/
|
||||
|
||||
# HTML documentation
|
||||
html_doc/
|
||||
|
||||
components/components/*
|
6
CMakeLists.txt
Executable file
6
CMakeLists.txt
Executable file
@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(I2c_test)
|
8
Makefile
Executable file
8
Makefile
Executable file
@ -0,0 +1,8 @@
|
||||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := i2c-simple
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
2
main/CMakeLists.txt
Executable file
2
main/CMakeLists.txt
Executable file
@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "i2c_simple_main.c" "led_controller.c" "DS4432U.c"
|
||||
INCLUDE_DIRS ".")
|
75
main/DS4432U.c
Normal file
75
main/DS4432U.c
Normal file
@ -0,0 +1,75 @@
|
||||
#include <stdio.h>
|
||||
#include "esp_log.h"
|
||||
#include "driver/i2c.h"
|
||||
|
||||
#define I2C_MASTER_SCL_IO CONFIG_I2C_MASTER_SCL /*!< GPIO number used for I2C master clock */
|
||||
#define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA /*!< GPIO number used for I2C master data */
|
||||
#define I2C_MASTER_NUM 0 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
|
||||
#define I2C_MASTER_FREQ_HZ 400000 /*!< I2C master clock frequency */
|
||||
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
|
||||
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
|
||||
#define I2C_MASTER_TIMEOUT_MS 1000
|
||||
|
||||
|
||||
//DS4432U+ -- Adjustable current DAC for use with the TPS40305 voltage regulator
|
||||
//address: 0x90
|
||||
#define DS4432U_SENSOR_ADDR 0x48 //Slave address of the DS4432U+
|
||||
#define DS4432U_OUT0_REG 0xF8 //register for current output 0
|
||||
#define DS4432U_OUT1_REG 0xF9 //register for current output 1
|
||||
|
||||
static const char *TAG = "DS4432U.c";
|
||||
|
||||
/**
|
||||
* @brief i2c master initialization
|
||||
*/
|
||||
esp_err_t i2c_master_init(void) {
|
||||
int i2c_master_port = I2C_MASTER_NUM;
|
||||
|
||||
i2c_config_t conf = {
|
||||
.mode = I2C_MODE_MASTER,
|
||||
.sda_io_num = I2C_MASTER_SDA_IO,
|
||||
.scl_io_num = I2C_MASTER_SCL_IO,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master.clk_speed = I2C_MASTER_FREQ_HZ,
|
||||
};
|
||||
|
||||
i2c_param_config(i2c_master_port, &conf);
|
||||
|
||||
return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief i2c master delete
|
||||
*/
|
||||
esp_err_t i2c_master_delete(void) {
|
||||
return i2c_driver_delete(I2C_MASTER_NUM);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read a sequence of I2C bytes
|
||||
*/
|
||||
static esp_err_t register_read(uint8_t i2c_address, uint8_t reg_addr, uint8_t *data, size_t len) {
|
||||
return i2c_master_write_read_device(I2C_MASTER_NUM, i2c_address, ®_addr, 1, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a byte to a I2C register
|
||||
*/
|
||||
// static esp_err_t register_write_byte(uint8_t i2c_address, uint8_t reg_addr, uint8_t data) {
|
||||
// int ret;
|
||||
// uint8_t write_buf[2] = {reg_addr, data};
|
||||
|
||||
// ret = i2c_master_write_to_device(I2C_MASTER_NUM, i2c_address, write_buf, sizeof(write_buf), I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS);
|
||||
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
void DS4432U_read(void) {
|
||||
uint8_t data[3];
|
||||
|
||||
/* Read the DS4432U+ WHO_AM_I register, on power up the register should have the value 0x00 */
|
||||
ESP_ERROR_CHECK(register_read(DS4432U_SENSOR_ADDR, DS4432U_OUT1_REG, data, 1));
|
||||
ESP_LOGI(TAG, "DS4432U+ OUT1 = 0x%02X", data[0]);
|
||||
}
|
10
main/DS4432U.h
Normal file
10
main/DS4432U.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef DS4432U_H_
|
||||
#define DS4432U_H_
|
||||
|
||||
#include "driver/i2c.h"
|
||||
|
||||
esp_err_t i2c_master_init(void);
|
||||
esp_err_t i2c_master_delete(void);
|
||||
void DS4432U_read(void);
|
||||
|
||||
#endif /* DS4432U_H_ */
|
17
main/Kconfig.projbuild
Executable file
17
main/Kconfig.projbuild
Executable file
@ -0,0 +1,17 @@
|
||||
menu "Example Configuration"
|
||||
|
||||
config I2C_MASTER_SCL
|
||||
int "SCL GPIO Num"
|
||||
default 6 if IDF_TARGET_ESP32C3
|
||||
default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
||||
help
|
||||
GPIO number for I2C Master clock line.
|
||||
|
||||
config I2C_MASTER_SDA
|
||||
int "SDA GPIO Num"
|
||||
default 5 if IDF_TARGET_ESP32C3
|
||||
default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
|
||||
help
|
||||
GPIO number for I2C Master data line.
|
||||
|
||||
endmenu
|
3
main/component.mk
Executable file
3
main/component.mk
Executable file
@ -0,0 +1,3 @@
|
||||
#
|
||||
# Main Makefile. This is basically the same as a component makefile .
|
||||
#
|
73
main/i2c_simple_main.c
Executable file
73
main/i2c_simple_main.c
Executable file
@ -0,0 +1,73 @@
|
||||
/* i2c - Simple example
|
||||
|
||||
Simple I2C example that shows how to initialize I2C
|
||||
as well as reading and writing from and to registers for a sensor connected over I2C.
|
||||
|
||||
For other examples please check:
|
||||
https://github.com/espressif/esp-idf/tree/master/examples
|
||||
|
||||
See README.md file to get detailed usage of this example.
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "esp_log.h"
|
||||
#include "driver/i2c.h"
|
||||
|
||||
#include "led_controller.h"
|
||||
#include "DS4432U.h"
|
||||
|
||||
static const char *TAG = "i2c-test";
|
||||
|
||||
//INA260 -- Power meter
|
||||
//address: 0x40
|
||||
#define INA260_SENSOR_ADDR 0x40 //Slave address of the INA260
|
||||
#define INA260_MANFID_REG 0xFE //should be 0x5449
|
||||
|
||||
//EMC2101 -- Fan and temp sensor controller
|
||||
//address: 0x4C
|
||||
#define EMC2101_SENSOR_ADDR 0x4C //Slave address of the EMC2101
|
||||
#define EMC2101_PRODUCTID_REG 0xFD //should be 0x16 or 0x28
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void app_main(void) {
|
||||
|
||||
//test the LEDs
|
||||
ESP_LOGI(TAG, "Init LEDs!");
|
||||
initLEDs();
|
||||
// gpio_set_level(LEDX_R, 1);
|
||||
// gpio_set_level(LEDZ_R, 1);
|
||||
|
||||
ledc_init();
|
||||
led_set();
|
||||
|
||||
ESP_ERROR_CHECK(i2c_master_init());
|
||||
ESP_LOGI(TAG, "I2C initialized successfully");
|
||||
|
||||
DS4432U_read();
|
||||
|
||||
// /* Read the EMC2101 WHO_AM_I register, on power up the register should have the value 0x16 or 0x28 */
|
||||
// ESP_ERROR_CHECK(register_read(EMC2101_SENSOR_ADDR, EMC2101_PRODUCTID_REG, data, 1));
|
||||
// ESP_LOGI(TAG, "EMC2101 PRODUCT ID = 0x%02X", data[0]);
|
||||
|
||||
// /* Read the INA260 WHO_AM_I register, on power up the register should have the value 0x5449 */
|
||||
// ESP_ERROR_CHECK(register_read(INA260_SENSOR_ADDR, INA260_MANFID_REG, data, 2));
|
||||
// ESP_LOGI(TAG, "INA260 MANF ID = 0x%02X%02X", data[0], data[1]);
|
||||
|
||||
// /* Read the DS4432U+ WHO_AM_I register, on power up the register should have the value 0x00 */
|
||||
// ESP_ERROR_CHECK(register_read(DS4432U_SENSOR_ADDR, DS4432U_OUT1_REG, data, 1));
|
||||
// ESP_LOGI(TAG, "DS4432U+ OUT1 = 0x%02X", data[0]);
|
||||
|
||||
// /* Demonstrate writing by reseting the MPU9250 */
|
||||
// ESP_ERROR_CHECK(mpu9250_register_write_byte(MPU9250_PWR_MGMT_1_REG_ADDR, 1 << MPU9250_RESET_BIT));
|
||||
|
||||
ESP_ERROR_CHECK(i2c_master_delete());
|
||||
ESP_LOGI(TAG, "I2C unitialized successfully");
|
||||
}
|
126
main/led_controller.c
Normal file
126
main/led_controller.c
Normal file
@ -0,0 +1,126 @@
|
||||
#include <stdio.h>
|
||||
#include "esp_err.h"
|
||||
#include "driver/ledc.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
//LEDS
|
||||
#define LEDX_R GPIO_NUM_35
|
||||
#define LEDX_G GPIO_NUM_36
|
||||
#define LEDX_B GPIO_NUM_37
|
||||
#define LEDZ_R GPIO_NUM_38
|
||||
#define LEDZ_G GPIO_NUM_39
|
||||
#define LEDZ_B GPIO_NUM_40
|
||||
|
||||
void initLEDs(void) {
|
||||
gpio_set_direction(LEDX_R, GPIO_MODE_OUTPUT);
|
||||
gpio_set_direction(LEDX_G, GPIO_MODE_OUTPUT);
|
||||
gpio_set_direction(LEDX_B, GPIO_MODE_OUTPUT);
|
||||
gpio_set_direction(LEDZ_R, GPIO_MODE_OUTPUT);
|
||||
gpio_set_direction(LEDZ_G, GPIO_MODE_OUTPUT);
|
||||
gpio_set_direction(LEDZ_B, GPIO_MODE_OUTPUT);
|
||||
|
||||
gpio_set_level(LEDX_R, 0);
|
||||
gpio_set_level(LEDX_G, 0);
|
||||
gpio_set_level(LEDX_B, 0);
|
||||
gpio_set_level(LEDZ_R, 0);
|
||||
gpio_set_level(LEDZ_G, 0);
|
||||
gpio_set_level(LEDZ_B, 0);
|
||||
}
|
||||
|
||||
void ledc_init(void) {
|
||||
// Prepare and then apply the LEDC PWM timer configuration
|
||||
ledc_timer_config_t ledc_timer = {
|
||||
.speed_mode = LEDC_LOW_SPEED_MODE,
|
||||
.timer_num = LEDC_TIMER_0,
|
||||
.duty_resolution = LEDC_TIMER_12_BIT, // Set duty resolution to 12 bits
|
||||
.freq_hz = 5000, // Set output frequency at 5 kHz
|
||||
.clk_cfg = LEDC_AUTO_CLK
|
||||
};
|
||||
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
|
||||
|
||||
// Prepare and then apply the LEDC PWM channel configuration
|
||||
ledc_channel_config_t ledc_channel0 = {
|
||||
.speed_mode = LEDC_LOW_SPEED_MODE,
|
||||
.channel = LEDC_CHANNEL_0,
|
||||
.timer_sel = LEDC_TIMER_0,
|
||||
.intr_type = LEDC_INTR_DISABLE,
|
||||
.gpio_num = 35, // Define the output GPIO
|
||||
.duty = 0, // Set duty to 0%
|
||||
.hpoint = 0
|
||||
};
|
||||
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel0));
|
||||
|
||||
ledc_channel_config_t ledc_channel1 = {
|
||||
.speed_mode = LEDC_LOW_SPEED_MODE,
|
||||
.channel = LEDC_CHANNEL_1,
|
||||
.timer_sel = LEDC_TIMER_0,
|
||||
.intr_type = LEDC_INTR_DISABLE,
|
||||
.gpio_num = 36, // Define the output GPIO
|
||||
.duty = 0, // Set duty to 0%
|
||||
.hpoint = 0
|
||||
};
|
||||
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel1));
|
||||
|
||||
ledc_channel_config_t ledc_channel2 = {
|
||||
.speed_mode = LEDC_LOW_SPEED_MODE,
|
||||
.channel = LEDC_CHANNEL_2,
|
||||
.timer_sel = LEDC_TIMER_0,
|
||||
.intr_type = LEDC_INTR_DISABLE,
|
||||
.gpio_num = 37, // Define the output GPIO
|
||||
.duty = 0, // Set duty to 0%
|
||||
.hpoint = 0
|
||||
};
|
||||
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel2));
|
||||
|
||||
ledc_channel_config_t ledc_channel3 = {
|
||||
.speed_mode = LEDC_LOW_SPEED_MODE,
|
||||
.channel = LEDC_CHANNEL_3,
|
||||
.timer_sel = LEDC_TIMER_0,
|
||||
.intr_type = LEDC_INTR_DISABLE,
|
||||
.gpio_num = 38, // Define the output GPIO
|
||||
.duty = 0, // Set duty to 0%
|
||||
.hpoint = 0
|
||||
};
|
||||
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel3));
|
||||
|
||||
ledc_channel_config_t ledc_channel4 = {
|
||||
.speed_mode = LEDC_LOW_SPEED_MODE,
|
||||
.channel = LEDC_CHANNEL_4,
|
||||
.timer_sel = LEDC_TIMER_0,
|
||||
.intr_type = LEDC_INTR_DISABLE,
|
||||
.gpio_num = 39, // Define the output GPIO
|
||||
.duty = 0, // Set duty to 0%
|
||||
.hpoint = 0
|
||||
};
|
||||
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel4));
|
||||
|
||||
ledc_channel_config_t ledc_channel5 = {
|
||||
.speed_mode = LEDC_LOW_SPEED_MODE,
|
||||
.channel = LEDC_CHANNEL_5,
|
||||
.timer_sel = LEDC_TIMER_0,
|
||||
.intr_type = LEDC_INTR_DISABLE,
|
||||
.gpio_num = 40, // Define the output GPIO
|
||||
.duty = 0, // Set duty to 0%
|
||||
.hpoint = 0
|
||||
};
|
||||
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel5));
|
||||
}
|
||||
|
||||
void led_set(void) {
|
||||
ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 3000)); //r
|
||||
ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1, 1000)); //g
|
||||
ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_2, 0)); //b
|
||||
|
||||
ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_3, 3000)); //r
|
||||
ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_4, 1000)); //g
|
||||
ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_5, 0)); //b
|
||||
|
||||
// Update duty to apply the new value
|
||||
ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0));
|
||||
ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1));
|
||||
ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_2));
|
||||
|
||||
ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_3));
|
||||
ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_4));
|
||||
ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_5));
|
||||
}
|
8
main/led_controller.h
Normal file
8
main/led_controller.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef LED_CONTROLLER_H_
|
||||
#define LED_CONTROLLER_H_
|
||||
|
||||
void initLEDs(void);
|
||||
void ledc_init(void);
|
||||
void led_set(void);
|
||||
|
||||
#endif /* LED_CONTROLLER_H_ */
|
70
readme.md
Normal file → Executable file
70
readme.md
Normal file → Executable file
@ -1,37 +1,49 @@
|
||||
## ESP-Miner
|
||||
# I2C Simple Example
|
||||
|
||||
ESP-Miner is bitcoin miner software designed to run on the ESP32. It mines on ASICs such as the Bitmain BM1397. The [BitaxeMax](https://github.com/skot/bitaxe/tree/max) is a handy board for this!
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||

|
||||
## Overview
|
||||
|
||||
## Architecture
|
||||
- Uses the ESP-IDF Framework, which is based on FreeRTOS (no Linux involved)
|
||||
- Uses the ESP32 WiFi to connect to the network
|
||||
- The ESP32 is provisioned to the local WiFi over BLE using ESP SmartConfig
|
||||
This example demonstrates basic usage of I2C driver by reading and writing from a I2C connected sensor:
|
||||
|
||||
### Firmware
|
||||
- ESP-Miner connects to and verifies the attached mining ASIC.
|
||||
- Setting the baud rate, hashing frequency, and filling in some other mystery registers
|
||||
- This startup sequence for the BM1387 and BM1397 can be found in cgminer the Kano edition in [driver-gekko.c](https://github.com/kanoi/cgminer/blob/master/driver-gekko.c)
|
||||
If you have a new I2C application to go (for example, read the temperature data from external sensor with I2C interface), try this as a basic template, then add your own code.
|
||||
|
||||
- ESP-Miner connects to your pool or stratum server and subscribes to get the latest work.
|
||||
- This is done with [JSON-RPC](https://www.jsonrpc.org)
|
||||
- Via the [Stratum](https://braiins.com/stratum-v1/docs) protocol
|
||||
- [cJSON](https://github.com/DaveGamble/cJSON) seems like a good embedded library for doing this.
|
||||
- ESP-Miner gets the latest work and formats it to be sent to the mining ASIC.
|
||||
- There isn't much change here except for computing the midstates, and shifting some bytes around
|
||||
- Beware of endianess!
|
||||
- How do we do this? Examples in cgminer Kano edition.
|
||||
- I have started on this.. [check this](nm1397_protocol.md)
|
||||
- ESP-Miner sends this work to the mining ASIC over serial.
|
||||
## How to use example
|
||||
|
||||
- The Mining ASIC will report back any when it finds a hash over the difficulty (which)?
|
||||
- The catch here is that if it doesn't find a hash over the difficulty, it will not report back at all. So you need to keep track of the hashing frequency and the time so that you can send a new block header to be hashed.
|
||||
### Hardware Required
|
||||
|
||||
- ESP-Miner will report back to the pool over Stratum the results of mining.
|
||||
To run this example, you should have one ESP32, ESP32-S or ESP32-C based development board as well as a MPU9250. MPU9250 is a inertial measurement unit, which contains a accelerometer, gyroscope as well as a magnetometer, for more information about it, you can read the [PDF](https://invensense.tdk.com/wp-content/uploads/2015/02/PS-MPU-9250A-01-v1.1.pdf) of this sensor.
|
||||
|
||||
- All of the administrative stuff of running a miner like;
|
||||
- Set the BM1397 core voltage and current.
|
||||
- check the fan speed
|
||||
- check the BM1397 temperature
|
||||
- optimize the hashing frequency and core voltage for max efficiency
|
||||
#### Pin Assignment:
|
||||
|
||||
**Note:** The following pin assignments are used by default, you can change these in the `menuconfig` .
|
||||
|
||||
| | SDA | SCL |
|
||||
| ---------------- | -------------- | -------------- |
|
||||
| ESP I2C Master | I2C_MASTER_SDA | I2C_MASTER_SCL |
|
||||
| MPU9250 Sensor | SDA | SCL |
|
||||
|
||||
|
||||
For the actual default value of `I2C_MASTER_SDA` and `I2C_MASTER_SCL` see `Example Configuration` in `menuconfig`.
|
||||
|
||||
**Note: ** There’s no need to add an external pull-up resistors for SDA/SCL pin, because the driver will enable the internal pull-up resistors.
|
||||
|
||||
### Build and Flash
|
||||
|
||||
Enter `idf.py -p PORT flash monitor` to build, flash and monitor the project.
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example Output
|
||||
|
||||
```bash
|
||||
I (328) i2c-simple-example: I2C initialized successfully
|
||||
I (338) i2c-simple-example: WHO_AM_I = 71
|
||||
I (338) i2c-simple-example: I2C unitialized successfully
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
(For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you as soon as possible.)
|
||||
|
Loading…
x
Reference in New Issue
Block a user