I am using an ESP-12F and the ESP8266_RTOS_SDK to read the Temperature/Humidity from an Si7020-a20 connected via I2C. SDA is pin 2, SCL is pin 14 on this particular setup. I am using the release/3.4 branch from https://github.com/espressif/ESP8266_RTOS_SDK and Xtensa v8.4.0 toolchain for 64-bit Linux (Fedora) to build the project and upload it.
I would like to mention that I am able to use the Arduino framework with its Wire.h library to interact with the Si7020-a20 without issue and get accurate temperature and humidity readings, so I would think that the wiring is correct.
I have an oscilloscope on the way tomorrow so that I can try to debug this issue, but I thought someone might have an idea of what is going on before then.
I have posted the full code below. I am using this datasheet (https://www.digikey.com/en/htmldatashee ... sheet.html), referring to the instructions on page 21 for "No Hold Master Mode", I have also tried the "Hold Master Mode" with no luck.
Here is the error that I am getting:
make -j$(cat /proc/cpuinfo | grep processor | wc -l) flash monitor
Toolchain path: /.../.espressif/tools/xtensa-lx106-elf/esp-2020r3-49-gd5524c1-8.4.0/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc
Toolchain version: esp-2020r3-49-gd5524c1
Compiler version: 8.4.0
Python requirements from /.../ESP8266_RTOS_SDK/requirements.txt are satisfied.
App "device-a-frame" version: 9252808-dirty
CC build/main/main.o
AR build/main/libmain.a
Generating esp8266.project.ld
LD build/device-a-frame.elf
esptool.py v2.4.0
Flashing binaries to serial port /dev/ttyUSB0 (app at offset 0x10000)...
esptool.py v2.4.0
Connecting........_____....._____.
Chip is ESP8266EX
Features: WiFi
MAC: 58:bf:25:cb:8f:48
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Compressed 10432 bytes to 7022...
Wrote 10432 bytes (7022 compressed) at 0x00000000 in 0.6 seconds (effective 134.4 kbit/s)...
Hash of data verified.
Compressed 137664 bytes to 86060...
Wrote 137664 bytes (86060 compressed) at 0x00010000 in 7.6 seconds (effective 145.3 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 83...
Wrote 3072 bytes (83 compressed) at 0x00008000 in 0.0 seconds (effective 2051.8 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
MONITOR
/.../ESP8266_RTOS_SDK/tools/idf_monitor.py:322: DeprecationWarning: distutils Version classes are deprecated. Use packaging.version instead.
if StrictVersion(serial.VERSION) < StrictVersion('3.3.0'):
--- idf_monitor on /dev/ttyUSB0 74880 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ets Jan 8 2013,rst cause:2, boot mode:(3,6)
load 0x40100000, len 7040, room 16
tail 0
chksum 0xe2
load 0x3ffe8408, len 24, room 8
tail 0
chksum 0x6b
load 0x3ffe8420, len 3324, room 8
tail 4
chksum 0x43
csum 0x43
I (45) boot: ESP-IDF v3.4-39-g23a225a5 2nd stage bootloader
I (45) boot: compile time 16:16:50
I (45) qio_mode: Enabling default flash chip QIO
I (53) boot: SPI Speed : 40MHz
I (60) boot: SPI Mode : QIO
I (66) boot: SPI Flash Size : 2MB
I (72) boot: Partition Table:
I (77) boot: ## Label Usage Type ST Offset Length
I (89) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (100) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (112) boot: 2 factory factory app 00 00 00010000 000f0000
I (123) boot: End of partition table
I (130) esp_image: segment 0: paddr=0x00010010 vaddr=0x40210010 size=0x16f74 ( 94068) map
0x40210010: _stext at ??:?
I (175) esp_image: segment 1: paddr=0x00026f8c vaddr=0x40226f84 size=0x06048 ( 24648) map
I (184) esp_image: segment 2: paddr=0x0002cfdc vaddr=0x3ffe8000 size=0x003dc ( 988) load
I (186) esp_image: segment 3: paddr=0x0002d3c0 vaddr=0x40100000 size=0x00080 ( 128) load
I (200) esp_image: segment 4: paddr=0x0002d448 vaddr=0x40100080 size=0x0454c ( 17740) load
I (219) boot: Loaded app from partition at offset 0x10000
D (228) phy_init: loading PHY init data from application binary
D (244) nvs: nvs_open_from_partition backup_mac 0
D (247) nvs: nvs_get_str_or_blob backup_mac_data
D (250) nvs: nvs_close 1
D (252) system_api: Load MAC from NVS error=0
D (254) reset_reason: RTC reset 2 wakeup 0 store 0, reason is 2
D (261) wdt: Enable task watch dog panic, panic time parameter is 11
D (271) wdt: task watch dog trigger time parameter is 15
I (278) gpio: GPIO[2]| InputEn: 0| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
I (292) gpio: GPIO[14]| InputEn: 0| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
ESP_ERROR_CHECK failed: esp_err_t 0xffffffff (ESP_FAIL) at 0x402117e8
0x402117e8: _esp_error_check_failed at /.../ESP8266_RTOS_SDK/components/freertos/port/esp8266/panic.c:206
file: "main.c" line 37
func: app_main
expression: i2c_master_cmd_begin(I2C_MASTER_ADDRESS, cmd, 1000 / portTICK_RATE_MS)
abort() was called at PC 0x402117eb on core 0
0x402117eb: _esp_error_check_failed at /.../ESP8266_RTOS_SDK/components/freertos/port/esp8266/panic.c:207
Guru Meditation Error: Core 0 panic'ed (StoreProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x402139f6 PS : 0x00000030 A0 : 0x402139f4 A1 : 0x3ffea0e0
0x402139f6: abort at /.../ESP8266_RTOS_SDK/components/newlib/src/syscall.c:69 (discriminator 1)
0x402139f4: abort at /.../ESP8266_RTOS_SDK/components/newlib/src/syscall.c:69 (discriminator 1)
A2 : 0x00000000 A3 : 0xffffffdb A4 : 0x00000001 A5 : 0x00000001
A6 : 0x00000000 A7 : 0x40228de8 A8 : 0x3ffea0f0 A9 : 0x00000004
A10 : 0x00000000 A11 : 0x00000020 A12 : 0x3ffeb2d4 A13 : 0x00000000
A14 : 0x00000000 A15 : 0x00000000 SAR : 0x0000001e EXCCAUSE: 0x0000001d
Backtrace: 0x402139f6:0x3ffea0e0 0x402117ee:0x3ffea0f0 0x402135a1:0x3ffea100 0x40210b13:0x3ffea130
0x402139f6: abort at /.../ESP8266_RTOS_SDK/components/newlib/src/syscall.c:69 (discriminator 1)
0x402117ee: _esp_error_check_failed at ??:?
0x402135a1: app_main at /.../device-a-frame/main/main.c:38 (discriminator 2)
Here is the full code that I am using:
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "driver/i2c.h"
#define I2C_MASTER_ADDRESS I2C_NUM_0
void app_main()
{
i2c_config_t conf = {};
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = 2;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_io_num = 14;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.clk_stretch_tick = 300; // Not 100% sure about this value
ESP_ERROR_CHECK(i2c_driver_install(I2C_MASTER_ADDRESS, conf.mode)); // Install the Driver
ESP_ERROR_CHECK(i2c_param_config(I2C_MASTER_ADDRESS, &conf)); // Setup the Configuration
uint8_t data[2];
i2c_cmd_handle_t cmd = i2c_cmd_link_create(); // Create the link
i2c_master_start(cmd); // Issue Start Command
i2c_master_write_byte(cmd, 0x40 << 1 | I2C_MASTER_WRITE, true); // Slave Address + Write bit + Check ACK
i2c_master_write_byte(cmd, 0xF3, true); // Measure Command
i2c_master_start(cmd); // Repeated Start
i2c_master_write_byte(cmd, 0x40 << 1 | I2C_MASTER_READ, true); // Slave Address + Read bit + Check ACK
i2c_master_start(cmd); // Repeated Start
i2c_master_write_byte(cmd, 0x40 << 1 | I2C_MASTER_READ, true); // Slave Address + Read bit + Check ACK
// How do we account for "Device will NACK the slave address byte until conversion is complete." here???
i2c_master_read_byte(cmd, &data[0], I2C_MASTER_ACK); // Read MS byte and send ACK
i2c_master_read_byte(cmd, &data[1], I2C_MASTER_LAST_NACK); // Read LS Byte and send NACK
i2c_master_stop(cmd); // Issue Stop Command
ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_MASTER_ADDRESS, cmd, 1000 / portTICK_RATE_MS)); // Not 100% sure about the 1000 / portTick_RATE_MS
i2c_cmd_link_delete(cmd); // Delete the Link
i2c_driver_delete(I2C_MASTER_ADDRESS); // Delete the Driver
printf("data[0]: %d, data[1]: %d\n", data[0], data[1]); // data[0]: <int>, data[1]: <int>
int temperature = (((175.72 * (data[0] << 8 | data[1])) / 65536) - 46.85) * 1.8 + 32; // Convert to degrees fahrenheit
printf("Temperature reading: %d\n", temperature); // Temperature reading: <int>
}
I am not sure how to account for the "Clock stretch during measurement" in the "Hold Master Mode" or the "Device will NACK the slave address byte until conversion is complete." in the "No Hold Master Mode".
Any help would be greatly appreciated.