/* * 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 #include #include #include #include #include #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); }