i2c issues with Metro ESP32-S2

Please tell us which board you are using.
For CircuitPython issues, ask in the Adafruit CircuitPython forum.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
dirtknap
 
Posts: 1
Joined: Wed Sep 22, 2021 10:03 am

i2c issues with Metro ESP32-S2

Post by dirtknap »

Not sure if this is the right place to ask, but I'm having issues with setting up the Metro ESP32-S2 as an i2c slave using ESP-IDF though Platform IO.

I'm using a modified version of the ESP-IDF i2c example (https://github.com/espressif/esp-idf/tr ... _self_test). It deploys fine and the master portion works fine, but the slave part never acknowledges writes. I have confirmed this by using an another micro controller as slave (Arduino UNO) and another as master (Adafruit Metro M0). I even set up the metro M0 using a Arduino i2c scan sketch with the Metro 32-S2 and Uno on the circuit and the Uno address reports back, but the Metro 32-S2 doesn't. I have also tried other GPIO pins and swapping the i2c port number between master and slave as well as setting the Metro 32-S2 as just a slave.

I have tested it on an Adafruit Metro ESP32-S2 and a Feather ESP32-S2 and gotten the same results so I'm not sure if this is an ESP32-S2 specific issue or a code issue below is the code I am using on the ESP32-S2.

Any help would be apprecaited!

Code: Select all

#include <stdio.h>
#include "esp_log.h"
#include "driver/i2c.h"

static const char *TAG = "i2c-test";

#define SLAVE_BUFFER_LENGTH 512     /*!< Data buffer length of test buffer */
#define DATA_LENGTH 32              /*!< Data buffer length of test buffer */

#define I2C_MASTER_SCL_IO 34        //34 - mtero express    9 - feather esp32-s2
#define I2C_MASTER_SDA_IO 33      //33 - metro express   8 - feather esp32-s2
#define I2C_MASTER_NUM 1            /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
#define I2C_MASTER_FREQ_HZ 400000   /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_TIMEOUT_MS 1000

#define I2C_SLAVE_SCL_IO 4         //4 - metro esp32   11 - feather esp32-s2
#define I2C_SLAVE_SDA_IO 3        //3 - metro esp32   10 - feather esp32-s2
#define I2C_SLAVE_NUM 0              /*!< I2C port number for slave dev */
#define I2C_SLAVE_TX_BUF_LEN (2 * SLAVE_BUFFER_LENGTH) /*!< I2C slave tx buffer size */
#define I2C_SLAVE_RX_BUF_LEN (2 * SLAVE_BUFFER_LENGTH) /*!< I2C slave rx buffer size */

#define SLAVE_ADDR 0x04 /*!< Slave address*/

#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ   /*!< I2C master read */
#define ACK_CHECK_EN 0x1           /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0x0          /*!< I2C master will not check ack from slave */




static esp_err_t i2c_slave_init(void)
{
    int i2c_slave_port = I2C_SLAVE_NUM;
    i2c_config_t conf_slave = {
        .mode = I2C_MODE_SLAVE,
        .sda_io_num = I2C_SLAVE_SDA_IO,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_io_num = I2C_SLAVE_SCL_IO,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,   
        .slave.addr_10bit_en = 0,
        .slave.slave_addr = SLAVE_ADDR,
    };
    esp_err_t err = i2c_param_config(i2c_slave_port, &conf_slave);
    ESP_LOGI("slave1", "%d", err);
    err = i2c_driver_install(i2c_slave_port, conf_slave.mode, I2C_SLAVE_RX_BUF_LEN, I2C_SLAVE_TX_BUF_LEN, 0);
    ESP_LOGI("slave2", "%d", err);

    err = i2c_reset_rx_fifo(i2c_slave_port);
    ESP_LOGI("slave3", "%d", err);

    err = i2c_reset_tx_fifo(i2c_slave_port);
    ESP_LOGI("slave4", "%d", err);

    return err;
}

static void slaveRead(i2c_port_t i2c_num, uint8_t *data, size_t size)
{

    int read = i2c_slave_read_buffer(i2c_num, data, size, 1000 / portTICK_RATE_MS);

    printf("---- Slave read: [%d] bytes ----\n", read);

    if (read > 0)
    {
        int i;
        for (i = 0; i < read; i++)
        {
            printf("%02x ", data[i]);
            if ((i + 1) % 16 == 0)
            {
                printf("\n");
            }
        }
        printf("\n");
    }
}

static void i2c_slave_task(void *arg)
{
    uint8_t *data = (uint8_t *)malloc(SLAVE_BUFFER_LENGTH);

    while (1)
    {
        slaveRead(I2C_SLAVE_NUM, data, SLAVE_BUFFER_LENGTH);

        vTaskDelay(500 / portTICK_RATE_MS);
    }
    free(data);
    ESP_ERROR_CHECK(i2c_driver_delete(I2C_SLAVE_NUM));
    ESP_LOGI(TAG, "I2C slave unitialized successfully");
}

static esp_err_t i2c_master_init(void)
{
    int i2c_master_port = I2C_MASTER_NUM;

    i2c_config_t conf = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = I2C_MASTER_SDA_IO,
        .scl_io_num = I2C_MASTER_SCL_IO,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = I2C_MASTER_FREQ_HZ,
    };

    i2c_param_config(i2c_master_port, &conf);

    return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}

static esp_err_t write(i2c_port_t i2c_num, uint8_t *data, size_t size)
{

    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    esp_err_t err = i2c_master_start(cmd);
    ESP_LOGI("1", "%d", err);

    err = i2c_master_write_byte(cmd, (SLAVE_ADDR << 1) | WRITE_BIT, ACK_CHECK_EN);
    ESP_LOGI("2", "%d", err);

    err = i2c_master_write(cmd, data, size, ACK_CHECK_EN);
    ESP_LOGI("3", "%d", err);

    err = i2c_master_stop(cmd);
    ESP_LOGI("4", "%d", err);

    err = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_RATE_MS);
    ESP_LOGI("5", "%d", err);

    i2c_cmd_link_delete(cmd);
    return err;
}

static void i2c_master_task(void *arg)
{
    uint8_t *data = (uint8_t *)malloc(DATA_LENGTH);

    while (1)
    {

        for (int i = 0; i < DATA_LENGTH; i++)
        {
            data[i] = i + 10;
        }

        write(I2C_MASTER_NUM, data, DATA_LENGTH);

        vTaskDelay(2000 / portTICK_RATE_MS);
    }

    free(data);
    ESP_ERROR_CHECK(i2c_driver_delete(I2C_MASTER_NUM));
    ESP_LOGI(TAG, "I2C unitialized successfully");
}

void app_main(void)
{

    ESP_ERROR_CHECK(i2c_master_init());
    ESP_ERROR_CHECK(i2c_slave_init());
    ESP_LOGI(TAG, "I2C initialized successfully");

    xTaskCreate(&i2c_slave_task, "i2c_slave_task", 2048, NULL, 6, NULL);
    xTaskCreate(&i2c_master_task, "i2c_master_task", 2048, NULL, 5, NULL);
}

Locked
Please be positive and constructive with your questions and comments.

Return to “Metro, Metro Express, and Grand Central Boards”