mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(i2c_master): Add an api for retrieveing handle via port,
Closes https://github.com/espressif/esp-idf/issues/13968
This commit is contained in:
parent
c77ea73ca9
commit
992d8bc5f2
@ -127,7 +127,7 @@ static esp_err_t s_i2c_bus_handle_acquire(i2c_port_num_t port_num, i2c_bus_handl
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool i2c_bus_occupied(i2c_port_num_t port_num)
|
||||
bool i2c_bus_occupied(i2c_port_num_t port_num)
|
||||
{
|
||||
return s_i2c_platform.buses[port_num] != NULL;
|
||||
}
|
||||
|
@ -46,6 +46,15 @@ static const char *TAG = "i2c.master";
|
||||
#define I2C_FIFO_LEN(port_num) (SOC_I2C_FIFO_LEN)
|
||||
#endif
|
||||
|
||||
// Use the platform to same master bus handle
|
||||
typedef struct i2c_master_bus_platform_t i2c_master_bus_platform_t;
|
||||
|
||||
struct i2c_master_bus_platform_t {
|
||||
i2c_master_bus_handle_t handle[SOC_I2C_NUM];
|
||||
};
|
||||
|
||||
static i2c_master_bus_platform_t s_platform;
|
||||
|
||||
static esp_err_t s_i2c_master_clear_bus(i2c_bus_handle_t handle)
|
||||
{
|
||||
#if !SOC_I2C_SUPPORT_HW_CLR_BUS
|
||||
@ -989,6 +998,7 @@ esp_err_t i2c_new_master_bus(const i2c_master_bus_config_t *bus_config, i2c_mast
|
||||
xSemaphoreGive(i2c_master->cmd_semphr);
|
||||
|
||||
*ret_bus_handle = i2c_master;
|
||||
s_platform.handle[i2c_port_num] = i2c_master;
|
||||
return ESP_OK;
|
||||
|
||||
err:
|
||||
@ -1075,6 +1085,18 @@ esp_err_t i2c_master_bus_reset(i2c_master_bus_handle_t bus_handle)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t i2c_master_get_bus_handle(i2c_port_num_t port_num, i2c_master_bus_handle_t *ret_handle)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE((port_num < SOC_I2C_NUM), ESP_ERR_INVALID_ARG, TAG, "invalid i2c port number");
|
||||
if (i2c_bus_occupied(port_num) == false) {
|
||||
ESP_LOGE(TAG, "this port has not been initialized, please initialize it first");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
} else {
|
||||
*ret_handle = s_platform.handle[port_num];
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t i2c_master_multi_buffer_transmit(i2c_master_dev_handle_t i2c_dev, i2c_master_transmit_multi_buffer_info_t *buffer_info_array, size_t array_size, int xfer_timeout_ms)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(i2c_dev != NULL, ESP_ERR_INVALID_ARG, TAG, "i2c handle not initialized");
|
||||
|
@ -252,6 +252,14 @@ esp_err_t i2c_select_periph_clock(i2c_bus_handle_t handle, soc_module_clk_t clk_
|
||||
*/
|
||||
esp_err_t i2c_common_set_pins(i2c_bus_handle_t handle);
|
||||
|
||||
/**
|
||||
* @brief Check whether bus is acquired
|
||||
*
|
||||
* @param port_num number of port
|
||||
* @return true if the bus is occupied, false if the bus is not occupied.
|
||||
*/
|
||||
bool i2c_bus_occupied(i2c_port_num_t port_num);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
36
components/esp_driver_i2c/include/esp_private/i2c_platform.h
Normal file
36
components/esp_driver_i2c/include/esp_private/i2c_platform.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "driver/i2c_types.h"
|
||||
#include "hal/gpio_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Retrieves the I2C master bus handle for a specified I2C port number.
|
||||
*
|
||||
* This function retrieves the I2C master bus handle for the
|
||||
* given I2C port number. Please make sure the handle has already been initialized, and this
|
||||
* function would simply returns the existing handle. Note that the returned handle still can't be used concurrently
|
||||
*
|
||||
* @param port_num I2C port number for which the handle is to be retrieved.
|
||||
* @param ret_handle Pointer to a variable where the retrieved handle will be stored.
|
||||
* @return
|
||||
* - ESP_OK: Success. The handle is retrieved successfully.
|
||||
* - ESP_ERR_INVALID_ARG: Invalid argument, such as invalid port number
|
||||
* - ESP_ERR_INVALID_STATE: Invalid state, such as the I2C port is not initialized.
|
||||
*/
|
||||
esp_err_t i2c_master_get_bus_handle(i2c_port_num_t port_num, i2c_master_bus_handle_t *ret_handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -19,6 +19,7 @@
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/i2c_master.h"
|
||||
#include "esp_private/i2c_platform.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "test_utils.h"
|
||||
@ -345,3 +346,19 @@ TEST_CASE("I2C master transaction receive check nack return value", "[i2c]")
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, i2c_master_receive(dev_handle, data_rd, DATA_LENGTH, -1));
|
||||
_test_i2c_del_bus_device(bus_handle, dev_handle);
|
||||
}
|
||||
|
||||
TEST_CASE("Test get handle with known port", "[i2c]")
|
||||
{
|
||||
i2c_master_bus_handle_t handle;
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, i2c_master_get_bus_handle(10, &handle));
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, i2c_master_get_bus_handle(0, &handle));
|
||||
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
_test_i2c_new_bus_device(&bus_handle, &dev_handle);
|
||||
TEST_ESP_OK(i2c_master_get_bus_handle(0, &handle));
|
||||
|
||||
// Check the handle retrieved is as same as original handle
|
||||
TEST_ASSERT((uint32_t)bus_handle == (uint32_t)handle);
|
||||
_test_i2c_del_bus_device(bus_handle, dev_handle);
|
||||
}
|
||||
|
@ -150,6 +150,27 @@ Once the :cpp:type:`i2c_device_config_t` structure is populated with mandatory p
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
|
||||
|
||||
Get I2C master handle via port
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Given that i2c master handle has been initialized in some module(e.g. an audio module), an another module(e.g. a video module) is not convenient to reused the handle. We have a helper function, :cpp:func:`i2c_master_get_bus_handle` for getting the initialized handle via port. However, please make sure the handle has already been initialized ahead of time. Otherwise an error would be reported.
|
||||
|
||||
.. code:: c
|
||||
|
||||
// Source File 1
|
||||
#include "driver/i2c_master.h"
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
i2c_master_bus_config_t i2c_mst_config = {
|
||||
... // same as others
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
|
||||
|
||||
// Source File 2
|
||||
#include "esp_private/i2c_platform.h"
|
||||
#include "driver/i2c_master.h"
|
||||
i2c_master_bus_handle_t handle;
|
||||
ESP_ERROR_CHECK(i2c_master_get_bus_handle(0, &handle));
|
||||
|
||||
.. only:: SOC_LP_I2C_SUPPORTED
|
||||
|
||||
Install I2C master bus with LP I2C Peripheral
|
||||
|
Loading…
Reference in New Issue
Block a user