diff --git a/examples/peripherals/i2c/i2c_simple/CMakeLists.txt b/examples/peripherals/i2c/i2c_simple/CMakeLists.txt new file mode 100644 index 0000000000..d2742e102f --- /dev/null +++ b/examples/peripherals/i2c/i2c_simple/CMakeLists.txt @@ -0,0 +1,6 @@ +# 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.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(i2c-simple) diff --git a/examples/peripherals/i2c/i2c_simple/Makefile b/examples/peripherals/i2c/i2c_simple/Makefile new file mode 100644 index 0000000000..f8be8b947d --- /dev/null +++ b/examples/peripherals/i2c/i2c_simple/Makefile @@ -0,0 +1,8 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := i2c-simple + +include $(IDF_PATH)/make/project.mk diff --git a/examples/peripherals/i2c/i2c_simple/README.md b/examples/peripherals/i2c/i2c_simple/README.md new file mode 100644 index 0000000000..caac9b5b10 --- /dev/null +++ b/examples/peripherals/i2c/i2c_simple/README.md @@ -0,0 +1,49 @@ +# I2C Simple Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +## Overview + +This example demonstrates basic usage of I2C driver by reading and writing from a I2C connected sensor: + +If you have a new I2C application to go (for example, read the temperature data from external sensor with I2C interface), try this as a basic template, then add your own code. + +## How to use example + +### Hardware Required + +To run this example, you should have one ESP32, ESP32-S or ESP32-C based development board as well as a MPU9250. MPU9250 is a inertial measurement unit, which contains a accelerometer, gyroscope as well as a magnetometer, for more information about it, you can read the [PDF](https://invensense.tdk.com/wp-content/uploads/2015/02/PS-MPU-9250A-01-v1.1.pdf) of this sensor. + +#### Pin Assignment: + +**Note:** The following pin assignments are used by default, you can change these in the `menuconfig` . + +| | SDA | SCL | +| ---------------- | -------------- | -------------- | +| ESP I2C Master | I2C_MASTER_SDA | I2C_MASTER_SCL | +| MPU9250 Sensor | SDA | SCL | + + +For the actual default value of `I2C_MASTER_SDA` and `I2C_MASTER_SCL` see `Example Configuration` in `menuconfig`. + +**Note: ** There’s no need to add an external pull-up resistors for SDA/SCL pin, because the driver will enable the internal pull-up resistors. + +### Build and Flash + +Enter `idf.py -p PORT flash monitor` to build, flash and monitor the project. + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +```bash +I (328) i2c-simple-example: I2C initialized successfully +I (338) i2c-simple-example: WHO_AM_I = 71 +I (338) i2c-simple-example: I2C unitialized successfully +``` + +## Troubleshooting + +(For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you as soon as possible.) diff --git a/examples/peripherals/i2c/i2c_simple/main/CMakeLists.txt b/examples/peripherals/i2c/i2c_simple/main/CMakeLists.txt new file mode 100644 index 0000000000..fba1eeae46 --- /dev/null +++ b/examples/peripherals/i2c/i2c_simple/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "i2c_simple_main.c" + INCLUDE_DIRS ".") diff --git a/examples/peripherals/i2c/i2c_simple/main/Kconfig.projbuild b/examples/peripherals/i2c/i2c_simple/main/Kconfig.projbuild new file mode 100644 index 0000000000..dc9568c775 --- /dev/null +++ b/examples/peripherals/i2c/i2c_simple/main/Kconfig.projbuild @@ -0,0 +1,17 @@ +menu "Example Configuration" + + config I2C_MASTER_SCL + int "SCL GPIO Num" + default 6 if IDF_TARGET_ESP32C3 + default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + help + GPIO number for I2C Master clock line. + + config I2C_MASTER_SDA + int "SDA GPIO Num" + default 5 if IDF_TARGET_ESP32C3 + default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + help + GPIO number for I2C Master data line. + +endmenu diff --git a/examples/peripherals/i2c/i2c_simple/main/component.mk b/examples/peripherals/i2c/i2c_simple/main/component.mk new file mode 100644 index 0000000000..87e08136f5 --- /dev/null +++ b/examples/peripherals/i2c/i2c_simple/main/component.mk @@ -0,0 +1,3 @@ +# +# Main Makefile. This is basically the same as a component makefile . +# diff --git a/examples/peripherals/i2c/i2c_simple/main/i2c_simple_main.c b/examples/peripherals/i2c/i2c_simple/main/i2c_simple_main.c new file mode 100644 index 0000000000..e1dab040ef --- /dev/null +++ b/examples/peripherals/i2c/i2c_simple/main/i2c_simple_main.c @@ -0,0 +1,97 @@ +/* i2c - Simple example + + Simple I2C example that shows how to initialize I2C + as well as reading and writing from and to registers for a sensor connected over I2C. + + The sensor used in this example is a MPU9250 inertial measurement unit. + + For other examples please check: + https://github.com/espressif/esp-idf/tree/master/examples + + See README.md file to get detailed usage of this example. + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include "esp_log.h" +#include "driver/i2c.h" + +static const char *TAG = "i2c-simple-example"; + +#define I2C_MASTER_SCL_IO CONFIG_I2C_MASTER_SCL /*!< GPIO number used for I2C master clock */ +#define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA /*!< GPIO number used for I2C master data */ +#define I2C_MASTER_NUM 0 /*!< 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 MPU9250_SENSOR_ADDR 0x68 /*!< Slave address of the MPU9250 sensor */ +#define MPU9250_WHO_AM_I_REG_ADDR 0x75 /*!< Register addresses of the "who am I" register */ + +#define MPU9250_PWR_MGMT_1_REG_ADDR 0x6B /*!< Register addresses of the power managment register */ +#define MPU9250_RESET_BIT 7 + +/** + * @brief Read a sequence of bytes from a MPU9250 sensor registers + */ +static esp_err_t mpu9250_register_read(uint8_t reg_addr, uint8_t *data, size_t len) +{ + return i2c_master_write_read_device(I2C_MASTER_NUM, MPU9250_SENSOR_ADDR, ®_addr, 1, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); +} + +/** + * @brief Write a byte to a MPU9250 sensor register + */ +static esp_err_t mpu9250_register_write_byte(uint8_t reg_addr, uint8_t data) +{ + int ret; + uint8_t write_buf[2] = {reg_addr, data}; + + ret = i2c_master_write_to_device(I2C_MASTER_NUM, MPU9250_SENSOR_ADDR, write_buf, sizeof(write_buf), I2C_MASTER_TIMEOUT_MS / portTICK_RATE_MS); + + return ret; +} + +/** + * @brief i2c master initialization + */ +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); +} + + +void app_main(void) +{ + uint8_t data[2]; + ESP_ERROR_CHECK(i2c_master_init()); + ESP_LOGI(TAG, "I2C initialized successfully"); + + /* Read the MPU9250 WHO_AM_I register, on power up the register should have the value 0x71 */ + ESP_ERROR_CHECK(mpu9250_register_read(MPU9250_WHO_AM_I_REG_ADDR, data, 1)); + ESP_LOGI(TAG, "WHO_AM_I = %X", data[0]); + + /* Demonstrate writing by reseting the MPU9250 */ + ESP_ERROR_CHECK(mpu9250_register_write_byte(MPU9250_PWR_MGMT_1_REG_ADDR, 1 << MPU9250_RESET_BIT)); + + ESP_ERROR_CHECK(i2c_driver_delete(I2C_MASTER_NUM)); + ESP_LOGI(TAG, "I2C unitialized successfully"); +}