Skip to content

Instantly share code, notes, and snippets.

@cibomahto
Created July 4, 2021 18:41
Show Gist options
  • Save cibomahto/41c0d5703782938108408d9f02c25d13 to your computer and use it in GitHub Desktop.
Save cibomahto/41c0d5703782938108408d9f02c25d13 to your computer and use it in GitHub Desktop.
esp32 i2c with mutex
#include "master_i2c.h"
#include <driver/i2c.h>
#include <esp_log.h>
#include <freertos/FreeRTOS.h>
#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 SemaphoreHandle_t i2c_semaphore = NULL;
esp_err_t master_i2c_init()
{
// Don't initialize twice
if(i2c_semaphore != NULL)
return ESP_FAIL;
i2c_semaphore = xSemaphoreCreateMutex();
if(i2c_semaphore == NULL)
return ESP_FAIL;
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = CONFIG_I2C_SDA_GPIO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = CONFIG_I2C_SCL_GPIO,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = CONFIG_I2C_FREQ_KHZ * 1000,
};
esp_err_t ret;
ret = i2c_param_config(I2C_NUM_1, &conf);
if(ret != ESP_OK)
return ret;
ret = i2c_driver_install(I2C_NUM_1, conf.mode, 0, 0, 0);
if(ret != ESP_OK)
return ret;
return ESP_OK;
}
void master_i2c_write(uint8_t address, uint8_t reg, uint8_t* data, uint32_t size)
{
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, address << 1 | I2C_MASTER_WRITE, ACK_CHECK_EN);
i2c_master_write_byte(cmd, reg, ACK_CHECK_EN);
i2c_master_write(cmd, data, size, ACK_CHECK_EN);
i2c_master_stop(cmd);
xSemaphoreTake(i2c_semaphore, portMAX_DELAY);
i2c_master_cmd_begin(I2C_NUM_1, cmd, 0);
xSemaphoreGive(i2c_semaphore);
i2c_cmd_link_delete(cmd);
}
void master_i2c_read(uint8_t address, uint8_t reg, uint8_t* data, uint32_t size)
{
// Write the active address to the I2C device
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, address << 1 | I2C_MASTER_WRITE, ACK_CHECK_EN);
i2c_master_write_byte(cmd, reg, ACK_CHECK_EN);
// Then read the contents of that address
i2c_master_start(cmd);
i2c_master_write_byte(cmd, address << 1 | I2C_MASTER_READ, ACK_CHECK_EN);
i2c_master_read(cmd, data, size, I2C_MASTER_LAST_NACK);
i2c_master_stop(cmd);
xSemaphoreTake(i2c_semaphore, portMAX_DELAY);
i2c_master_cmd_begin(I2C_NUM_1, cmd, 0);
xSemaphoreGive(i2c_semaphore);
i2c_cmd_link_delete(cmd);
}
#pragma once
#include <stdint.h>
#include <esp_err.h>
//! @defgroup master_i2c Master I2C driver
//!
//! @brief Thread-safe Master I2C driver
//!
//! This driver uses the I2C_NUM_1 peripheral on the ESP32. Functions are multi-
//! thread safe, protected by an internal semaphore.
//! @{
//! @brief Initialize the I2C bus in master mode
//!
esp_err_t master_i2c_init();
//! @brief Make a write transaction on the I2C bus
//!
//! @param[in] address Address of I2C bus to write to (7-bit address, right-aligned)
//! @param[in] reg I2C register to write to
//! @param[in] data Pointer to memory location to read data from
//! @param[in] size Number of bytes to write
void master_i2c_write(uint8_t address, uint8_t reg, uint8_t* data, uint32_t size);
//! @brief Make a read transaction on the I2C bus
//!
//! @param[in] address Address of I2C bus to read from(7-bit address, right-aligned)
//! @param[in] reg I2C register to read from
//! @param[out] data Pointer to memory location to write data to
//! @param[in] size Number of bytes to read
void master_i2c_read(uint8_t address, uint8_t reg, uint8_t* data, uint32_t size);
//! @}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment