- I (26) boot: ESP-IDF v5.4 2nd stage bootloader
- I (26) boot: compile time Jan 31 2025 15:07:40
- I (26) boot: Multicore bootloader
- I (27) boot: chip revision: v0.1
- I (29) boot: efuse block revision: v1.2
- I (33) boot.esp32s3: Boot SPI Speed : 80MHz
- I (36) boot.esp32s3: SPI Mode : DIO
- I (40) boot.esp32s3: SPI Flash Size : 16MB
- I (44) boot: Enabling RNG early entropy source...
- I (49) boot: Partition Table:
- I (51) boot: ## Label Usage Type ST Offset Length
- I (57) boot: 0 nvs WiFi data 01 02 00009000 00006000
- I (64) boot: 1 phy_init RF data 01 01 0000f000 00001000
- I (70) boot: 2 factory factory app 00 00 00010000 00100000
- I (77) boot: End of partition table
- I (80) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=0bbf0h ( 48112) map
- I (96) esp_image: segment 1: paddr=0001bc18 vaddr=3fc93b00 size=02e64h ( 11876) load
- I (99) esp_image: segment 2: paddr=0001ea84 vaddr=40374000 size=01594h ( 5524) load
- I (104) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=1c360h (115552) map
- I (130) esp_image: segment 4: paddr=0003c388 vaddr=40375594 size=0e4e4h ( 58596) load
- I (144) esp_image: segment 5: paddr=0004a874 vaddr=600fe100 size=0001ch ( 28) load
- I (150) boot: Loaded app from partition at offset 0x10000
- I (150) boot: Disabling RNG early entropy source...
- I (161) octal_psram: vendor id : 0x0d (AP)
- I (161) octal_psram: dev id : 0x02 (generation 3)
- I (162) octal_psram: density : 0x03 (64 Mbit)
- I (164) octal_psram: good-die : 0x01 (Pass)
- I (168) octal_psram: Latency : 0x01 (Fixed)
- I (172) octal_psram: VCC : 0x01 (3V)
- I (176) octal_psram: SRF : 0x01 (Fast Refresh)
- I (181) octal_psram: BurstType : 0x01 (Hybrid Wrap)
- I (186) octal_psram: BurstLen : 0x01 (32 Byte)
- I (191) octal_psram: Readlatency : 0x02 (10 cycles@Fixed)
- I (196) octal_psram: DriveStrength: 0x00 (1/1)
- I (201) MSPI Timing: PSRAM timing tuning index: 4
- I (204) esp_psram: Found 8MB PSRAM device
- I (208) esp_psram: Speed: 80MHz
- I (211) cpu_start: Multicore app
- I (640) esp_psram: SPI SRAM memory test OK
- I (649) cpu_start: Pro cpu start user code
- I (649) cpu_start: cpu freq: 160000000 Hz
- I (649) app_init: Application information:
- I (649) app_init: Project name: i2c_IDF_5_4
- I (653) app_init: App version: 1
- I (657) app_init: Compile time: Jan 31 2025 15:07:21
- I (662) app_init: ELF file SHA256: 9f604b8ae...
- I (666) app_init: ESP-IDF: v5.4
- I (670) efuse_init: Min chip rev: v0.0
- I (674) efuse_init: Max chip rev: v0.99
- I (678) efuse_init: Chip rev: v0.1
- I (681) heap_init: Initializing. RAM available for dynamic allocation:
- I (688) heap_init: At 3FC972C8 len 00052448 (329 KiB): RAM
- I (693) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM
- I (698) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
- I (703) heap_init: At 600FE11C len 00001ECC (7 KiB): RTCRAM
- I (709) esp_psram: Adding pool of 8192K of PSRAM memory to heap allocator
- I (716) spi_flash: detected chip: gd
- I (718) spi_flash: flash io: dio
- I (721) sleep_gpio: Configure to isolate all GPIO pins in sleep state
- I (728) sleep_gpio: Enable automatic switching of GPIO sleep configuration
- I (735) main_task: Started on CPU0
- I (738) esp_psram: Reserving pool of 32K of internal memory for DMA/internal allocations
- I (746) main_task: Calling app_main()
- I (749) gpio: GPIO[10]| InputEn: 1| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
- I (758) gpio: GPIO[17]| InputEn: 1| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
- Guru Meditation Error: Core 0 panic'ed (Interrupt wdt timeout on CPU0).
- Core 0 register dump:
- PC : 0x4037bf9d PS : 0x00060034 A0 : 0x8037b8dd A1 : 0x3fc94b90
- --- Error: ClearCommError failed (PermissionError(13, 'Das Gerät erkennt den Befehl nicht.', None, 22))
- --- Waiting for the device to reconnect--- 0x4037bf9d: spinlock_release at C:/Espressif/idf/v5.4/esp-idf/components/esp_hw_support/include/spinlock.h:183
- (inlined by) vPortExitCritical at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:501
- A2 : 0x3c030da8 A3 : 0xffffffff A4 : 0x00000000 A5 : 0x00060023
- A6 : 0x00000000 A7 : 0x0000cdcd A8 : 0x3fc96f14 A9 : 0x00000002
- A10 : 0x00000000 A11 : 0xb33fffff A12 : 0x0000cdcd A13 : 0x00060023
- A14 : 0x00000003 A15 : 0x0000cdcd SAR : 0x00000016 EXCCAUSE: 0x00000005
- EXCVADDR: 0x00000000 LBEG : 0x40056f5c LEND : 0x40056f72 LCOUNT : 0xffffffff
- --- 0x40056f5c: memcpy in ROM
- 0x40056f72: memcpy in ROM
- Core 0 was running in ISR context:
- EPC1 : 0x4201a61f EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x4037bf9d
- --- 0x4201a61f: uart_hal_write_txfifo at C:/Espressif/idf/v5.4/esp-idf/components/hal/uart_hal_iram.c:27
- 0x4037bf9d: spinlock_release at C:/Espressif/idf/v5.4/esp-idf/components/esp_hw_support/include/spinlock.h:183
- (inlined by) vPortExitCritical at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:501
- Backtrace: 0x4037bf9a:0x3fc94b90 0x4037b8da:0x3fc94bb0 0x403785fe:0x3fc94bd0 0x4037672d:0x3fc94c10 0x40377401:0x3fc94c30 0x400559dd:0x3fc9aa70 0x4037c01e:0x3fc9aa80 0x4037ba75:0x3fc9aaa0 0x4200e0b5:0x3fc9aae0 0x4200e2ec:0x3fc9ab10 0x4200e3ce:0x3fc9ab50 0x4200f1df:0x3fc9ab80 0x4200a042:0x3fc9ac10 0x4200a13f:0x3fc9ad10 0x4201bbb3:0x3fc9ad30 0x4037bc85:0x3fc9ad60
- .--- 0x4037bf9a: spinlock_release at C:/Espressif/idf/v5.4/esp-idf/components/esp_hw_support/include/spinlock.h:181 (discriminator 1)
- (inlined by) vPortExitCritical at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:501 (discriminator 1)
- 0x4037b8da: xQueueGenericSendFromISR at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/queue.c:1339
- 0x403785fe: i2c_master_isr_handler_default at C:/Espressif/idf/v5.4/esp-idf/components/esp_driver_i2c/i2c_master.c:704
- 0x4037672d: shared_intr_isr at C:/Espressif/idf/v5.4/esp-idf/components/esp_hw_support/intr_alloc.c:445
- 0x40377401: _xt_lowint1 at C:/Espressif/idf/v5.4/esp-idf/components/xtensa/xtensa_vectors.S:1240
- 0x400559dd: _xtos_set_intlevel in ROM
- 0x4037c01e: vPortClearInterruptMaskFromISR at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h:560
- (inlined by) vPortExitCritical at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:514
- 0x4037ba75: xQueueReceive at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/queue.c:1632
- 0x4200e0b5: s_i2c_send_commands at C:/Espressif/idf/v5.4/esp-idf/components/esp_driver_i2c/i2c_master.c:513
- 0x4200e2ec: s_i2c_transaction_start at C:/Espressif/idf/v5.4/esp-idf/components/esp_driver_i2c/i2c_master.c:625
- 0x4200e3ce: s_i2c_synchronous_transaction at C:/Espressif/idf/v5.4/esp-idf/components/esp_driver_i2c/i2c_master.c:918
- 0x4200f1df: i2c_master_transmit_receive at C:/Espressif/idf/v5.4/esp-idf/components/esp_driver_i2c/i2c_master.c:1214
- 0x4200a042: app_main_cpp() at D:/usr/esp/i2c_IDF_5_4/main/main.cpp:105
- 0x4200a13f: app_main at D:/usr/esp/i2c_IDF_5_4/main/main.cpp:40
- 0x4201bbb3: main_task at C:/Espressif/idf/v5.4/esp-idf/components/freertos/app_startup.c:208
- 0x4037bc85: vPortTaskWrapper at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:139
- Core 1 register dump:
- PC : 0x403788fa PS : 0x00060734 A0 : 0x82002c89 A1 : 0x3fc9bbc0
- --- 0x403788fa: esp_cpu_wait_for_intr at C:/Espressif/idf/v5.4/esp-idf/components/esp_hw_support/cpu.c:64
- A2 : 0x00000000 A3 : 0x00000000 A4 : 0x3fc98a00 A5 : 0x3fc989e0
- A6 : 0x40375fec A7 : 0x00000001 A8 : 0x8200c8ae A9 : 0x3fc9bb80
- --- 0x40375fec: ipc_task at C:/Espressif/idf/v5.4/esp-idf/components/esp_system/esp_ipc.c:53
- A10 : 0x00000000 A11 : 0x00000000 A12 : 0x3fc989e0 A13 : 0x3fc989c0
- A14 : 0x00000001 A15 : 0x3fc9bd94 SAR : 0x00000000 EXCCAUSE: 0x00000005
- EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
- Backtrace: 0x403788f7:0x3fc9bbc0 0x42002c86:0x3fc9bbe0 0x4037cbb1:0x3fc9bc00 0x4037bc85:0x3fc9bc20
- .--- 0x403788f7: xt_utils_wait_for_intr at C:/Espressif/idf/v5.4/esp-idf/components/xtensa/include/xt_utils.h:82
- (inlined by) esp_cpu_wait_for_intr at C:/Espressif/idf/v5.4/esp-idf/components/esp_hw_support/cpu.c:55
- 0x42002c86: esp_vApplicationIdleHook at C:/Espressif/idf/v5.4/esp-idf/components/esp_system/freertos_hooks.c:58
- 0x4037cbb1: prvIdleTask at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/tasks.c:4353 (discriminator 1)
- 0x4037bc85: vPortTaskWrapper at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:139
- ELF file SHA256: 9f604b8ae
- Rebooting...
I have a really strange problem here, which is very hard to track down, but I made a very simple minimum project which shows the problem:
I made a data logging project, starting with IDF 5.2.3 on a Lilygo T7-S3-board with a DS3231 RTC and a SHT40 temperature sensor, written in C++. With IDF 5.2.3 everything worked perfect for many weeks.
Now I'd like to update to IDF 5.4 and I'm running in serious problems when I'm talking to my I2C devices. The problem is, that the IRQ watchdog gets fired in the driver's IRQ function. But I can't find any reason for this. The hardware is absolutely fine and the test code is so simple, that I'm sure that the problem is NOT here (keep in mind, that the test code is working 100 % OK with IDF 5.2.3).
Have a look at line 110 in main.cpp: Commenting out the unused class "DS3231 Uhr" will lead to a working program again.
Uncommenting this line will lead to a core 0 panic right BEFORE any code of the classes are executed (line 105, have a look at the monitor output)!
But there's nothing in the class constructor which could lead to any memory corruption. I checked the stack size (8192 bytes) which is more than sufficient. I switched on every stack and heap tracing and checking functions. No stack overflow or any other problem.
I don't have any idea why this happens, but it seems to be related using C++.
I attached the simple test program with the configurations. Switching fore and back the IDF from 5.2.3 to 5.4 will show a working program with 5.2.3 and a failing program with a core 0 panic on IDF 5.4.
Any ideas what to do?
Thanks and bye, Oliver
main.cpp
- /*
- * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
- *
- * SPDX-License-Identifier: Unlicense OR CC0-1.0
- */
- #include <string.h>
- #include <stdio.h>
- #include "esp_log.h"
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "driver/i2c_master.h"
- #include "driver/gpio.h"
- #include "main.h"
- // Uhr und ADC(Druck) am I2C-Bus 0
- #define PIN_SDA_BUS0 GPIO_NUM_13
- #define PIN_SCL_BUS0 GPIO_NUM_14
- // Temperatursensor und Luftfeuchte am I2C-Bus
- #define PIN_SDA_BUS1 GPIO_NUM_21
- #define PIN_SCL_BUS1 GPIO_NUM_18
- #define MASTER_FREQUENCY 400000
- #define PORT_NUMBER -1
- #define LENGTH 48
- #define SHT40_ADDR (0x44)
- #define DS3231_ADDR (0x68)
- #define DEV_TIMEOUT 1000
- // GPIOs
- #define BOARD_LED GPIO_NUM_17
- #define SWITCH_BRIDGE_AND_CLOCK GPIO_NUM_10
- void app_main_cpp();
- extern "C"
- {
- void app_main()
- {
- app_main_cpp();
- }
- }
- void app_main_cpp()
- {
- // Outputs
- const uint64_t OutputBitMask = (1ULL << BOARD_LED) | (1ULL << SWITCH_BRIDGE_AND_CLOCK);
- gpio_config_t ConfigOutput = {};
- ConfigOutput.pin_bit_mask = OutputBitMask;
- ConfigOutput.mode = GPIO_MODE_INPUT_OUTPUT; // damit man auch den aktuell eingestellten Wert zurücklesen kann!
- ConfigOutput.pull_up_en = GPIO_PULLUP_DISABLE;
- ConfigOutput.pull_down_en = GPIO_PULLDOWN_DISABLE;
- ConfigOutput.intr_type = GPIO_INTR_DISABLE;
- ESP_ERROR_CHECK(gpio_config(&ConfigOutput));
- // DS3231M
- i2c_master_bus_config_t BusConfig0 = {};
- BusConfig0.clk_source = I2C_CLK_SRC_DEFAULT;
- BusConfig0.i2c_port = -1;
- BusConfig0.scl_io_num = PIN_SCL_BUS0;
- BusConfig0.sda_io_num = PIN_SDA_BUS0;
- BusConfig0.glitch_ignore_cnt = 7;
- BusConfig0.flags.enable_internal_pullup = 1;
- // SHT40
- i2c_master_bus_config_t BusConfig1 = {};
- BusConfig1.clk_source = I2C_CLK_SRC_DEFAULT;
- BusConfig1.i2c_port = -1;
- BusConfig1.scl_io_num = PIN_SCL_BUS1;
- BusConfig1.sda_io_num = PIN_SDA_BUS1;
- BusConfig1.glitch_ignore_cnt = 7;
- BusConfig1.flags.enable_internal_pullup = 1;
- i2c_master_bus_handle_t BusHandle0, BusHandle1;
- ESP_ERROR_CHECK(i2c_new_master_bus(&BusConfig0, &BusHandle0));
- ESP_ERROR_CHECK(i2c_new_master_bus(&BusConfig1, &BusHandle1));
- i2c_device_config_t SHTConfig, ClockConfig;
- i2c_master_dev_handle_t iSHTHandle, iClockHandle;
- ClockConfig.dev_addr_length = I2C_ADDR_BIT_LEN_7;
- ClockConfig.device_address = DS3231_ADDR;
- ClockConfig.scl_speed_hz = MASTER_FREQUENCY;
- ESP_ERROR_CHECK(i2c_master_bus_add_device(BusHandle0, &ClockConfig, &iClockHandle));
- SHTConfig.dev_addr_length = I2C_ADDR_BIT_LEN_7;
- SHTConfig.device_address = SHT40_ADDR;
- SHTConfig.scl_speed_hz = MASTER_FREQUENCY;
- ESP_ERROR_CHECK(i2c_master_bus_add_device(BusHandle1, &SHTConfig, &iSHTHandle));
- uint8_t rb[7] = {0};
- // Echtzeituhr einschalten
- gpio_set_level(SWITCH_BRIDGE_AND_CLOCK, 1);
- vTaskDelay(pdMS_TO_TICKS(1));
- #define DS3231_ADDR_TIME 0x00
- for (int i = 0; i < 5; i++)
- {
- // DS3231
- uint8_t RegAddr=0x00;
- ESP_ERROR_CHECK(i2c_master_transmit_receive(iClockHandle, &RegAddr, 1, rb, 7, DEV_TIMEOUT));
- ESP_LOGI("DS3231:", "%x %x %x %x %x %x %x", rb[0], rb[1], rb[2], rb[3], rb[4], rb[5], rb[6]);
- vTaskDelay(pdMS_TO_TICKS(1000));
- }
- DS3231 Uhr;
- SHT40 Thermo;
- ESP_ERROR_CHECK(Thermo.Init(BusHandle1, SHT40_ADDR, MASTER_FREQUENCY));
- float MyTemp, MyHum;
- bool CRCErr;
- for (;;)
- {
- ESP_ERROR_CHECK(Thermo.Read(MyTemp, MyHum, CRCErr));
- ESP_LOGI("TEMP:", "%.2f°C", MyTemp);
- vTaskDelay(pdMS_TO_TICKS(1000));
- }
- }
- SHT40::SHT40()
- {
- mDevHandle = NULL;
- mBusHandle = NULL;
- }
- esp_err_t SHT40::Init(i2c_master_bus_handle_t aBusHandle, uint8_t aI2CAddr, uint32_t aI2CSpeed_Hz)
- {
- mBusHandle = aBusHandle;
- i2c_device_config_t conf={};
- conf.dev_addr_length = I2C_ADDR_BIT_LEN_7;
- conf.device_address = aI2CAddr;
- conf.scl_speed_hz = aI2CSpeed_Hz;
- conf.scl_wait_us = 1000000;
- return i2c_master_bus_add_device(mBusHandle, &conf, &mDevHandle);
- }
- SHT40::~SHT40(void)
- {
- if (mDevHandle != NULL)
- i2c_master_bus_rm_device(mDevHandle);
- }
- // SHT40-Sensor auslesen
- esp_err_t SHT40::Read(float &aTemp, float &aHum, bool &rCRC_Err)
- {
- int ret;
- rCRC_Err = false;
- uint8_t mode = 0xFD;
- ret = i2c_master_transmit(mDevHandle, &mode, 1, DEV_TIMEOUT);
- if (ret != ESP_OK)
- {
- ESP_LOGE("SHT40::Read", "I2C error no.: %d", ret);
- return ret;
- }
- int iWaitTime_ms = 200;
- vTaskDelay(iWaitTime_ms / portTICK_PERIOD_MS);
- // Belegung Datenblock in bytes:
- // Temperatur_high, Temperatur_low, Temperatur_crc, Luftfeuchte_high, Luftfeuchte_low, Luftfeuchte_crc
- uint8_t rb[6] = {0};
- ret = i2c_master_receive(mDevHandle, rb, 6, DEV_TIMEOUT);
- if (ret != ESP_OK)
- {
- ESP_LOGE("SHT40::Read", "I2C error no.: %d", ret);
- return ret;
- }
- aTemp = -45 + 175 * (double)(rb[0] * 256 + rb[1]) / 65535.0;
- aHum = -6 + 125 * (double)(rb[3] * 256 + rb[4]) / 65535.0;
- return ret;
- }
- DS3231::DS3231()
- {
- mDevHandle = NULL;
- mBusHandle = NULL;
- }
- DS3231::~DS3231(void)
- {
- if (mDevHandle != NULL)
- i2c_master_bus_rm_device(mDevHandle);
- }
- esp_err_t DS3231::Init(i2c_master_bus_handle_t aBusHandle, uint8_t aI2CAddr, uint32_t aI2CSpeed_Hz)
- {
- mBusHandle = aBusHandle;
- if (aBusHandle == NULL)
- return ESP_ERR_INVALID_ARG;
- i2c_device_config_t conf={};
- conf.dev_addr_length = I2C_ADDR_BIT_LEN_7;
- conf.device_address = aI2CAddr;
- conf.scl_speed_hz = aI2CSpeed_Hz;
- return i2c_master_bus_add_device(mBusHandle, &conf, &mDevHandle);
- }
- esp_err_t DS3231::WriteReg(uint8_t aReg, uint8_t *aWriteBuf, uint8_t aWriteSize)
- {
- if (mDevHandle == NULL)
- return ESP_ERR_INVALID_ARG;
- esp_err_t ret;
- uint8_t *WriteData = new uint8_t[aWriteSize + 1];
- WriteData[0] = aReg;
- memcpy(WriteData + 1, aWriteBuf, aWriteSize);
- // Die Register der Uhr beschreiben sich recht langsam. 100 ms Timeout sind da zu wenig!
- ret = i2c_master_transmit(mDevHandle, WriteData, aWriteSize + 1, 1000);
- delete[] WriteData;
- if (ret != ESP_OK)
- ESP_LOGE("DS3231::WriteRegister", "I2C error no.: %d", ret);
- return ret;
- }
- esp_err_t DS3231::ReadReg(uint8_t aReg, uint8_t *aReadBuf, uint8_t aReadSize)
- {
- if (mDevHandle == NULL)
- return ESP_ERR_INVALID_ARG;
- esp_err_t ret;
- uint8_t RegAddr[1] = {aReg};
- ret = i2c_master_transmit_receive(mDevHandle, RegAddr, 1, aReadBuf, aReadSize, DEV_TIMEOUT);
- // uint8_t RegAddr=aReg;
- // ret = i2c_master_transmit_receive(mDevHandle, &RegAddr, 1, aReadBuf, aReadSize, DEV_TIMEOUT);
- if (ret != ESP_OK)
- ESP_LOGE("DS3231::ReadRegister", "I2C error no.: %d", ret);
- return ret;
- }
- esp_err_t DS3231::GetTime(struct tm *time)
- {
- uint8_t data[7];
- /* read time */
- ESP_LOGI("DS3231", "Start Reading 7 I2C bytes...");
- esp_err_t res = ReadReg(0x00, data, 7);
- if (res != ESP_OK)
- return res;
- ESP_LOGI("DS3231", "Read 7 I2C bytes!");
- return ESP_OK;
- }
- #ifndef __MAIN_H__
- #define __MAIN_H__
- #include "driver/i2c_master.h"
- class SHT40
- {
- private:
- i2c_master_bus_handle_t mBusHandle;
- i2c_master_dev_handle_t mDevHandle;
- uint8_t mReadMode;
- public:
- SHT40();
- ~SHT40(void);
- esp_err_t Init(i2c_master_bus_handle_t aBusHandle, uint8_t aI2CAddr, uint32_t aI2CSpeed_Hz);
- esp_err_t Read(float &aTemp, float &aHum, bool &rCRC_Err);
- };
- class DS3231
- {
- private:
- i2c_master_bus_handle_t mBusHandle;
- i2c_master_dev_handle_t mDevHandle;
- esp_err_t WriteReg(uint8_t aReg, uint8_t *aWriteBuf, uint8_t aWriteSize);
- esp_err_t ReadReg(uint8_t aReg, uint8_t *aReadBuf, uint8_t aReadSize);
- public:
- DS3231();
- esp_err_t Init(i2c_master_bus_handle_t aBusHandle, uint8_t aI2CAddr, uint32_t aI2CSpeed_Hz);
- ~DS3231(void);
- esp_err_t GetTime(struct tm *time);
- };
- #endif