Inital Working Commit with I2C Version 2

This commit is contained in:
simon 2025-12-02 16:18:03 +01:00
commit b99bee4018
9 changed files with 1774 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.cache
build
sdkconfig.*

8
CMakeLists.txt Normal file
View File

@ -0,0 +1,8 @@
# 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.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
idf_build_set_property(MINIMAL_BUILD ON)
project(hello_world)

100
I2C_Example.drawio Normal file
View File

@ -0,0 +1,100 @@
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (X11; Linux x86_64; rv:145.0) Gecko/20100101 Firefox/145.0" version="29.2.2">
<diagram name="Seite-1" id="xmF2k3mIiioUrtqv9CFb">
<mxGraphModel dx="807" dy="428" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="zR9owv5O9vHcoRiZ2yGH-1" parent="1" style="rounded=0;whiteSpace=wrap;html=1;" value="&lt;div&gt;ESP32C3&lt;/div&gt;&lt;div&gt;Slave&lt;/div&gt;" vertex="1">
<mxGeometry height="60" width="120" x="220" y="270" as="geometry" />
</mxCell>
<mxCell id="zR9owv5O9vHcoRiZ2yGH-2" parent="1" style="rounded=0;whiteSpace=wrap;html=1;" value="&lt;div&gt;ESP32C3&lt;/div&gt;&lt;div&gt;Master&lt;/div&gt;" vertex="1">
<mxGeometry height="60" width="120" x="500" y="270" as="geometry" />
</mxCell>
<mxCell id="zR9owv5O9vHcoRiZ2yGH-5" edge="1" parent="1" style="endArrow=none;html=1;rounded=0;entryX=0.75;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" value="">
<mxGeometry height="50" relative="1" width="50" as="geometry">
<Array as="points">
<mxPoint x="610" y="230" />
</Array>
<mxPoint x="580" y="270" as="sourcePoint" />
<mxPoint x="610" y="270" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="zR9owv5O9vHcoRiZ2yGH-7" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="P4 to GND" vertex="1">
<mxGeometry height="30" width="60" x="610" y="230" as="geometry" />
</mxCell>
<mxCell id="zR9owv5O9vHcoRiZ2yGH-10" parent="1" style="rounded=0;whiteSpace=wrap;html=1;" value="&lt;div&gt;4,7k&lt;/div&gt;" vertex="1">
<mxGeometry height="20" width="30" x="460" y="380" as="geometry" />
</mxCell>
<mxCell id="zR9owv5O9vHcoRiZ2yGH-11" parent="1" style="rounded=0;whiteSpace=wrap;html=1;" value="&lt;div&gt;4,7k&lt;/div&gt;" vertex="1">
<mxGeometry height="20" width="30" x="460" y="350" as="geometry" />
</mxCell>
<mxCell id="zR9owv5O9vHcoRiZ2yGH-12" edge="1" parent="1" source="zR9owv5O9vHcoRiZ2yGH-11" style="endArrow=none;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" target="zR9owv5O9vHcoRiZ2yGH-1" value="">
<mxGeometry height="50" relative="1" width="50" as="geometry">
<Array as="points">
<mxPoint x="310" y="360" />
</Array>
<mxPoint x="430" y="360" as="sourcePoint" />
<mxPoint x="480" y="310" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="zR9owv5O9vHcoRiZ2yGH-13" edge="1" parent="1" source="zR9owv5O9vHcoRiZ2yGH-1" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" target="zR9owv5O9vHcoRiZ2yGH-10" value="">
<mxGeometry height="50" relative="1" width="50" as="geometry">
<Array as="points">
<mxPoint x="280" y="390" />
</Array>
<mxPoint x="430" y="360" as="sourcePoint" />
<mxPoint x="480" y="310" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="zR9owv5O9vHcoRiZ2yGH-14" edge="1" parent="1" source="zR9owv5O9vHcoRiZ2yGH-11" style="endArrow=none;html=1;rounded=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" target="zR9owv5O9vHcoRiZ2yGH-2" value="">
<mxGeometry height="50" relative="1" width="50" as="geometry">
<Array as="points">
<mxPoint x="475" y="315" />
</Array>
<mxPoint x="430" y="360" as="sourcePoint" />
<mxPoint x="480" y="310" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="zR9owv5O9vHcoRiZ2yGH-15" edge="1" parent="1" source="zR9owv5O9vHcoRiZ2yGH-10" style="endArrow=none;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" target="zR9owv5O9vHcoRiZ2yGH-11" value="">
<mxGeometry height="50" relative="1" width="50" as="geometry">
<mxPoint x="430" y="360" as="sourcePoint" />
<mxPoint x="480" y="310" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="zR9owv5O9vHcoRiZ2yGH-18" edge="1" parent="1" source="zR9owv5O9vHcoRiZ2yGH-2" style="endArrow=none;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0.25;exitY=1;exitDx=0;exitDy=0;" target="zR9owv5O9vHcoRiZ2yGH-11" value="">
<mxGeometry height="50" relative="1" width="50" as="geometry">
<Array as="points">
<mxPoint x="530" y="360" />
</Array>
<mxPoint x="430" y="360" as="sourcePoint" />
<mxPoint x="480" y="310" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="zR9owv5O9vHcoRiZ2yGH-19" edge="1" parent="1" source="zR9owv5O9vHcoRiZ2yGH-10" style="endArrow=none;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=1;exitY=0.25;exitDx=0;exitDy=0;" target="zR9owv5O9vHcoRiZ2yGH-2" value="">
<mxGeometry height="50" relative="1" width="50" as="geometry">
<Array as="points">
<mxPoint x="560" y="385" />
</Array>
<mxPoint x="430" y="360" as="sourcePoint" />
<mxPoint x="480" y="310" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="zR9owv5O9vHcoRiZ2yGH-20" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="&lt;div&gt;VCC&lt;/div&gt;&lt;div&gt;3,3V&lt;/div&gt;" vertex="1">
<mxGeometry height="30" width="60" x="440" y="285" as="geometry" />
</mxCell>
<mxCell id="zR9owv5O9vHcoRiZ2yGH-21" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="P9" vertex="1">
<mxGeometry height="30" width="60" x="540" y="330" as="geometry" />
</mxCell>
<mxCell id="zR9owv5O9vHcoRiZ2yGH-22" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="P9" vertex="1">
<mxGeometry height="30" width="60" x="240" y="330" as="geometry" />
</mxCell>
<mxCell id="zR9owv5O9vHcoRiZ2yGH-23" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="P8" vertex="1">
<mxGeometry height="30" width="60" x="290" y="330" as="geometry" />
</mxCell>
<mxCell id="zR9owv5O9vHcoRiZ2yGH-24" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="P8" vertex="1">
<mxGeometry height="30" width="60" x="490" y="330" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

BIN
I2C_Example.drawio.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

15
Makefile Normal file
View File

@ -0,0 +1,15 @@
all:
echo "no default rule"
export:
source ~/esp/esp-idf/export.fish && fish
buildIdf:
idf.py build
flashMini:
idf.py flash -p /dev/ttyACM0
monitorMini:
idf.py monitor -p /dev/ttyACM0

32
README.md Normal file
View File

@ -0,0 +1,32 @@
# I2C Master Send, Slave Receive Example
# !IMPORTANT
Use I2C Version 2 (activate it in menuconfig I2C_ENABLE_SLAVE_DRIVER_VERSION_2)
## Test Setup
- 2 x ESP32C3
- 4 x Jumper Kabel
- 2 x 4,7kΩ
![Example Setup](I2C_Example.drawio.png)
I2C Bus Pulled Up to 3,3V
## Flash the Program and Monitor
```bash
idf.py flash -p /dev/ttyACM0
idf.py flash -p /dev/ttyACM1
```
```bash
idf.py monitor -p /dev/ttyACM0
idf.py monitor -p /dev/ttyACM1
```
You should see
`Received from master: Hello I2C`
and
`Master Sending Data`

3
main/CMakeLists.txt Normal file
View File

@ -0,0 +1,3 @@
idf_component_register(SRCS "main.c"
PRIV_REQUIRES spi_flash driver
INCLUDE_DIRS "")

155
main/main.c Normal file
View File

@ -0,0 +1,155 @@
/*
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include "driver/gpio.h"
#include "driver/i2c_master.h"
#include "driver/i2c_slave.h"
#include "esp_attr.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/idf_additions.h"
#include "freertos/projdefs.h"
#include "freertos/task.h"
#include "portmacro.h"
#include "sdkconfig.h"
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/_intsup.h>
#define TEST_I2C_PORT 0
#define I2C_MASTER_SCL_IO 9
#define I2C_MASTER_SDA_IO 8
#define I2C_SLAVE_SCL_IO 9
#define I2C_SLAVE_SDA_IO 8
#define ESP_SLAVE_ADDR 0x28
#define I2C_SLAVE_NUM 0
#define MASTER_MODE_PIN 4 // pin pulled to ground to set master
#define DATA_LEN 64
typedef struct {
QueueHandle_t event_queue;
i2c_slave_dev_handle_t handle;
} i2c_context_t;
typedef struct {
uint8_t buf[DATA_LEN];
// size_t buf_len; i2c version 2 themes to have this in its data, not needed
// for example
} i2c_slave_message_t;
static i2c_context_t context;
static IRAM_ATTR uint8_t rx_buf[DATA_LEN];
void master_task(void *param) {
i2c_master_bus_config_t i2c_mst_config = {
.clk_source = I2C_CLK_SRC_DEFAULT,
.i2c_port = TEST_I2C_PORT,
.scl_io_num = I2C_MASTER_SCL_IO,
.sda_io_num = I2C_MASTER_SDA_IO,
.glitch_ignore_cnt = 7,
};
i2c_master_bus_handle_t bus_handle;
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
i2c_device_config_t dev_cfg = {
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
.device_address = ESP_SLAVE_ADDR,
.scl_speed_hz = 100000,
};
i2c_master_dev_handle_t dev_handle;
ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
uint8_t data_wr[] = "Hello I2C\n";
while (true) {
ESP_ERROR_CHECK(
i2c_master_transmit(dev_handle, data_wr, sizeof(data_wr), -1));
printf("Master Sending Data\n");
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
static IRAM_ATTR bool
i2c_slave_receive_cb(i2c_slave_dev_handle_t i2c_slave,
const i2c_slave_rx_done_event_data_t *evt_data,
void *arg) {
i2c_context_t *ctx = (i2c_context_t *)arg;
i2c_slave_message_t msg = {};
if (evt_data->length > DATA_LEN) {
return false;
}
memcpy(msg.buf, evt_data->buffer, evt_data->length);
BaseType_t task_woken = pdFALSE;
xQueueSendFromISR(ctx->event_queue, &msg, &task_woken);
return task_woken;
}
void slave_task(void *param) {
i2c_slave_config_t cfg = {
.i2c_port = I2C_SLAVE_NUM,
//.clk_source = I2C_CLK_SRC_DEFAULT,
.scl_io_num = I2C_SLAVE_SCL_IO,
.sda_io_num = I2C_SLAVE_SDA_IO,
.slave_addr = ESP_SLAVE_ADDR,
.send_buf_depth = 64,
.receive_buf_depth = 64,
};
context.event_queue = xQueueCreate(10, sizeof(i2c_slave_message_t));
i2c_slave_dev_handle_t slave;
ESP_ERROR_CHECK(i2c_new_slave_device(&cfg, &slave));
i2c_slave_event_callbacks_t cbs = {
.on_receive = i2c_slave_receive_cb,
};
ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave, &cbs, &context));
i2c_slave_message_t msg;
while (true) {
if (xQueueReceive(context.event_queue, &msg, portMAX_DELAY)) {
printf("Received from master: %s\n", msg.buf);
}
}
}
void app_main(void) {
printf("I2C Example\n");
// GPIO-Pin für Moduserkennung
gpio_reset_pin(MASTER_MODE_PIN);
gpio_set_direction(MASTER_MODE_PIN, GPIO_MODE_INPUT);
bool isMaster = (gpio_get_level(MASTER_MODE_PIN) == 0);
if (isMaster) {
printf("Started in Master Mode Register Task Master\n");
xTaskCreate(master_task, "MasterTask", 4096, NULL, 1, NULL);
} else {
printf("Started in Slave Mode Register Task Slave\n");
xTaskCreate(slave_task, "MasterTask", 4096, NULL, 1, NULL);
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}

1458
sdkconfig Normal file

File diff suppressed because it is too large Load Diff