/
i2c_slave.h
166 lines (154 loc) · 8.03 KB
/
i2c_slave.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
* SPDX-FileCopyrightText: 2023 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"
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief I2C slave specific configurations
*/
typedef struct {
i2c_port_num_t i2c_port; /*!< I2C port number, `-1` for auto selecting */
gpio_num_t sda_io_num; /*!< SDA IO number used by I2C bus */
gpio_num_t scl_io_num; /*!< SCL IO number used by I2C bus */
i2c_clock_source_t clk_source; /*!< Clock source of I2C bus. */
uint32_t send_buf_depth; /*!< Depth of internal transfer ringbuffer, increase this value can support more transfers pending in the background */
uint16_t slave_addr; /*!< I2C slave address */
i2c_addr_bit_len_t addr_bit_len; /*!< I2C slave address in bit length */
int intr_priority; /*!< I2C interrupt priority, if set to 0, driver will select the default priority (1,2,3). */
struct {
#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE
uint32_t stretch_en: 1; /*!< Enable slave stretch */
#endif
#if SOC_I2C_SLAVE_SUPPORT_BROADCAST
uint32_t broadcast_en: 1; /*!< I2C slave enable broadcast */
#endif
#if SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS
uint32_t access_ram_en: 1; /*!< Can get access to I2C RAM directly */
#endif
#if SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH
uint32_t slave_unmatch_en: 1; /*!< Can trigger unmatch interrupt when slave address does not match what master sends*/
#endif
} flags; /*!< I2C slave config flags */
} i2c_slave_config_t;
/**
* @brief Group of I2C slave callbacks (e.g. get i2c slave stretch cause). But take care of potential concurrency issues.
* @note The callbacks are all running under ISR context
* @note When CONFIG_I2C_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM.
* The variables used in the function should be in the SRAM as well.
*/
typedef struct {
#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE
i2c_slave_stretch_callback_t on_stretch_occur; /*!< I2C slave stretched callback */
#endif
i2c_slave_received_callback_t on_recv_done; /*!< I2C slave receive done callback */
} i2c_slave_event_callbacks_t;
/**
* @brief Initialize an I2C slave device
*
* @param[in] slave_config I2C slave device configurations
* @param[out] ret_handle Return a generic I2C device handle
* @return
* - ESP_OK: I2C slave device initialized successfully
* - ESP_ERR_INVALID_ARG: I2C device initialization failed because of invalid argument.
* - ESP_ERR_NO_MEM: Create I2C device failed because of out of memory.
*/
esp_err_t i2c_new_slave_device(const i2c_slave_config_t *slave_config, i2c_slave_dev_handle_t *ret_handle);
/**
* @brief Deinitialize the I2C slave device
*
* @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`.
* @return
* - ESP_OK: Delete I2C device successfully.
* - ESP_ERR_INVALID_ARG: I2C device initialization failed because of invalid argument.
*/
esp_err_t i2c_del_slave_device(i2c_slave_dev_handle_t i2c_slave);
/**
* @brief Read bytes from I2C internal buffer. Start a job to receive I2C data.
*
* @note This function is non-blocking, it initiates a new receive job and then returns.
* User should check the received data from the `on_recv_done` callback that registered by `i2c_slave_register_event_callbacks()`.
*
* @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`.
* @param[out] data Buffer to store data from I2C fifo. Should be valid until `on_recv_done` is triggered.
* @param[in] buffer_size Buffer size of data that provided by users.
* @return
* - ESP_OK: I2C slave receive success.
* - ESP_ERR_INVALID_ARG: I2C slave receive parameter invalid.
* - ESP_ERR_NOT_SUPPORTED: This function should be work in fifo mode, but I2C_SLAVE_NONFIFO mode is configured
*/
esp_err_t i2c_slave_receive(i2c_slave_dev_handle_t i2c_slave, uint8_t *data, size_t buffer_size);
/**
* @brief Write bytes to internal ringbuffer of the I2C slave data. When the TX fifo empty, the ISR will
* fill the hardware FIFO with the internal ringbuffer's data.
*
* @note If you connect this slave device to some master device, the data transaction direction is from slave
* device to master device.
*
* @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`.
* @param[in] data Buffer to write to slave fifo, can pickup by master. Can be freed after this function returns. Equal or larger than `size`.
* @param[in] size In bytes, of `data` buffer.
* @param[in] xfer_timeout_ms Wait timeout, in ms. Note: -1 means wait forever.
* @return
* - ESP_OK: I2C slave transmit success.
* - ESP_ERR_INVALID_ARG: I2C slave transmit parameter invalid.
* - ESP_ERR_TIMEOUT: Operation timeout(larger than xfer_timeout_ms) because the device is busy or hardware crash.
* - ESP_ERR_NOT_SUPPORTED: This function should be work in fifo mode, but I2C_SLAVE_NONFIFO mode is configured
*/
esp_err_t i2c_slave_transmit(i2c_slave_dev_handle_t i2c_slave, const uint8_t *data, int size, int xfer_timeout_ms);
/**
* @brief Set I2C slave event callbacks for I2C slave channel.
*
* @note User can deregister a previously registered callback by calling this function and setting the callback member in the `cbs` structure to NULL.
* @note When CONFIG_I2C_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM.
* The variables used in the function should be in the SRAM as well. The `user_data` should also reside in SRAM.
*
* @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`.
* @param[in] cbs Group of callback functions
* @param[in] user_data User data, which will be passed to callback functions directly
* @return
* - ESP_OK: Set I2C transaction callbacks successfully
* - ESP_ERR_INVALID_ARG: Set I2C transaction callbacks failed because of invalid argument
* - ESP_FAIL: Set I2C transaction callbacks failed because of other error
*/
esp_err_t i2c_slave_register_event_callbacks(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_event_callbacks_t *cbs, void *user_data);
#if SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS
/**
* @brief Read bytes from I2C internal ram. This can be only used when `access_ram_en` in configuration structure set to true.
*
* @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`.
* @param[in] ram_address The offset of RAM (Cannot larger than I2C RAM memory)
* @param[out] data Buffer to store data read from I2C ram.
* @param[in] receive_size Received size from RAM.
* @return
* - ESP_OK: I2C slave transmit success.
* - ESP_ERR_INVALID_ARG: I2C slave transmit parameter invalid.
* - ESP_ERR_NOT_SUPPORTED: This function should be work in non-fifo mode, but I2C_SLAVE_FIFO mode is configured
*/
esp_err_t i2c_slave_read_ram(i2c_slave_dev_handle_t i2c_slave, uint8_t ram_address, uint8_t *data, size_t receive_size);
/**
* @brief Write bytes to I2C internal ram. This can be only used when `access_ram_en` in configuration structure set to true.
*
* @param[in] i2c_slave I2C slave device handle that created by `i2c_new_slave_device`.
* @param[in] ram_address The offset of RAM (Cannot larger than I2C RAM memory)
* @param[in] data Buffer to fill.
* @param[in] size Received size from RAM.
* @return
* - ESP_OK: I2C slave transmit success.
* - ESP_ERR_INVALID_ARG: I2C slave transmit parameter invalid.
* - ESP_ERR_INVALID_SIZE: Write size is larger than
* - ESP_ERR_NOT_SUPPORTED: This function should be work in non-fifo mode, but I2C_SLAVE_FIFO mode is configured
*/
esp_err_t i2c_slave_write_ram(i2c_slave_dev_handle_t i2c_slave, uint8_t ram_address, const uint8_t *data, size_t size);
#endif
#ifdef __cplusplus
}
#endif