QEMU: How to Control the Virtual I2C TMP105

sgmustadio
Posts: 8
Joined: Thu Mar 04, 2021 4:33 am

QEMU: How to Control the Virtual I2C TMP105

Postby sgmustadio » Tue Mar 11, 2025 6:10 pm

I'm trying to figure out how to control the virtual TMP105 built into the Espressif fork of QEMU. If I build/run with "idf.py qemu" it magically works (reads from the virtual I2C TMP105 at addr 0x48). How do I change the temperature in qemu?

Here is the code:

Code: Select all

#include <stdio.h>

#include "driver/i2c_master.h"
#include "freertos/FreeRTOS.h"

// Settings
static const i2c_port_num_t i2c_port = 0;           // -1 for auto-select
static const gpio_num_t i2c_sda_pin = 5;            // GPIO number for SDA
static const gpio_num_t i2c_scl_pin = 6;            // GPIO number for SCL
static const uint8_t i2c_glitch_ignore_cnt = 7;     // 7 is typical
static const uint16_t tmp10x_addr = 0x48;           // TMP102/105 I2C address
static const uint32_t tmp10x_scl_speed_hz = 100000; // 100kHz (standard mode)
static const uint32_t sleep_time_ms = 1000;

// Constants
static const uint8_t tmp10x_reg_temp = 0x00;

void app_main(void)
{
    esp_err_t esp_ret;
    i2c_master_bus_handle_t i2c_bus;
    i2c_master_dev_handle_t tmp10x_dev;
    uint8_t reg;
    uint8_t data[2];
    int16_t temperature;

    // Set I2C bus configuration
    i2c_master_bus_config_t bus_config = {
        .i2c_port = i2c_port,
        .sda_io_num = i2c_sda_pin,
        .scl_io_num = i2c_scl_pin,
        .clk_source = I2C_CLK_SRC_DEFAULT,
        .glitch_ignore_cnt = i2c_glitch_ignore_cnt,
        .flags.enable_internal_pullup = true,
    };

    // Initialize the I2C bus
    esp_ret = i2c_new_master_bus(&bus_config, &i2c_bus);
    if (esp_ret != ESP_OK) {
        printf("Error: Failed to initialize I2C bus\r\n");
        abort();
    }

    // Set I2C device configuration
    i2c_device_config_t dev_config = {
        .dev_addr_length = I2C_ADDR_BIT_LEN_7,
        .device_address = tmp10x_addr,
        .scl_speed_hz = tmp10x_scl_speed_hz,
    };

    // Initialize the TMP10x I2C device on the bus
    esp_ret = i2c_master_bus_add_device(i2c_bus, &dev_config, &tmp10x_dev);
    if (esp_ret != ESP_OK) {
        printf("Error: Failed to initialize I2C device\r\n");
        abort();
    }

    // Superloop
    while (1) {

        // Delay
        vTaskDelay(sleep_time_ms / portTICK_PERIOD_MS);

        // Store register address in buffer
        reg = tmp10x_reg_temp;

        // Read temperature
        esp_ret = i2c_master_transmit_receive(tmp10x_dev, &reg, 1, data, 2, -1);
        if (esp_ret != ESP_OK) {
            printf("Error: Failed to read temperature\r\n");
            continue;
        }

        // Convert data to temperature (deg C)
        temperature = (data[0] << 8) | data[1];
        temperature >>= 4;
        temperature *= 0.0625;

        // Print temperature
        printf("Temperature: %d deg C\r\n", temperature);
    }
}
Run with QEMU:

Code: Select all

root@2d39595f9a4d:/workspace/apps/i2c_temperature_demo# idf.py qemu
Adding "qemu"'s dependency "all" to list of commands with default set of options.
Executing action: all (aliases: build)
Running ninja in directory /workspace/apps/i2c_temperature_demo/build
Executing "ninja all"...
[1/4] cd /workspace/apps/i2c_temperature_demo/build/esp-idf/esptool...tition-table.bin /workspace/apps/i2c_temperature_demo/build/app.bin
app.bin binary size 0x307e0 bytes. Smallest app partition is 0x100000 bytes. 0xcf820 bytes (81%) free.
[1/1] cd /workspace/apps/i2c_temperature_demo/build/bootloader/esp-...workspace/apps/i2c_temperature_demo/build/bootloader/bootloader.bin
Bootloader binary size 0x6560 bytes. 0xaa0 bytes (9%) free.
[4/4] Completed 'bootloader'Executing action: qemu
Generating flash image: /workspace/apps/i2c_temperature_demo/build/qemu_flash.bin
esptool.py --chip=esp32 merge_bin --output=/workspace/apps/i2c_temperature_demo/build/qemu_flash.bin --fill-flash-size=2MB --flash_mode dio --flash_freq 40m --flash_size 2MB 0x1000 bootloader/bootloader.bin 0x10000 app.bin 0x8000 partition_table/partition-table.bin
esptool.py v4.8.1
SHA digest in image updated
Wrote 0x200000 bytes to file /workspace/apps/i2c_temperature_demo/build/qemu_flash.bin, ready to flash to offset 0x0
Using existing efuse image: /workspace/apps/i2c_temperature_demo/build/qemu_efuse.bin
Running qemu (fg): qemu-system-xtensa -M esp32 -m 4M -drive file=/workspace/apps/i2c_temperature_demo/build/qemu_flash.bin,if=mtd,format=raw -drive file=/workspace/apps/i2c_temperature_demo/build/qemu_efuse.bin,if=none,format=raw,id=efuse -global driver=nvram.esp32.efuse,property=drive,value=efuse -global driver=timer.esp32.timg,property=wdt_disable,value=true -nic user,model=open_eth -nographic -serial mon:stdio
Adding SPI flash device
ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x12 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:6276
load:0x40078000,len:15716
load:0x40080400,len:4
ho 8 tail 4 room 4
load:0x40080404,len:3860
entry 0x4008063c
I (929) boot: ESP-IDF v5.4 2nd stage bootloader
I (931) boot: compile time Mar 11 2025 17:35:55
I (931) boot: Multicore bootloader
I (1068) boot: chip revision: v3.0
I (1071) boot.esp32: SPI Speed      : 40MHz
I (1071) boot.esp32: SPI Mode       : DIO
I (1072) boot.esp32: SPI Flash Size : 2MB
I (1116) boot: Enabling RNG early entropy source...
I (1163) boot: Partition Table:
I (1163) boot: ## Label            Usage          Type ST Offset   Length
I (1164) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (1165) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (1166) boot:  2 factory          factory app      00 00 00010000 00100000
I (1208) boot: End of partition table
I (1249) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=0aefch ( 44796) map
I (1382) esp_image: segment 1: paddr=0001af24 vaddr=3ff80000 size=0001ch (    28) load
I (1508) esp_image: segment 2: paddr=0001af48 vaddr=3ffb0000 size=0236ch (  9068) load
I (1636) esp_image: segment 3: paddr=0001d2bc vaddr=40080000 size=02d5ch ( 11612) load
I (1758) esp_image: segment 4: paddr=00020020 vaddr=400d0020 size=163ech ( 91116) map
I (1899) esp_image: segment 5: paddr=00036414 vaddr=40082d5c size=0a3a8h ( 41896) load
I (2031) boot: Loaded app from partition at offset 0x10000
I (2032) boot: Disabling RNG early entropy source...
I (2092) cpu_start: Multicore app
I (3760) cpu_start: Pro cpu start user code
I (3762) cpu_start: cpu freq: 160000000 Hz
I (3763) app_init: Application information:
I (3763) app_init: Project name:     app
I (3764) app_init: App version:      1
I (3764) app_init: Compile time:     Mar 11 2025 17:35:42
I (3765) app_init: ELF file SHA256:  578be62c8...
I (3766) app_init: ESP-IDF:          v5.4
I (3766) efuse_init: Min chip rev:     v0.0
I (3767) efuse_init: Max chip rev:     v3.99 
I (3767) efuse_init: Chip rev:         v3.0
I (3769) heap_init: Initializing. RAM available for dynamic allocation:
I (3771) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (3771) heap_init: At 3FFB2C48 len 0002D3B8 (180 KiB): DRAM
I (3772) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (3773) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (3774) heap_init: At 4008D104 len 00012EFC (75 KiB): IRAM
I (3832) spi_flash: detected chip: winbond
I (3837) spi_flash: flash io: dio
I (3857) main_task: Started on CPU0
I (3867) main_task: Calling app_main()
Temperature: 25 deg C
Temperature: 25 deg C
Temperature: 25 deg C
Temperature: 25 deg C

Who is online

Users browsing this forum: ChatGPT-User and 5 guests